Я хотел бы преобразовать это:
foo^bar
ba^rfoo
oofrab
raboof^
В это:
FOObar
BArfoo
oofrab
RABOOF
Все, что находится перед «^» (или другим специальным символом, если это облегчает), становится заглавным.
Кроме того, удаление «^» также не требуется, если это облегчает его.
Использование GNU sed
(Значение по умолчанию Ubuntu) (благодаря pabouk для -r
предложение опции):
< inputfile sed -r 's/^(.*)\^/\U\1\E/' > out
Используя perl
(благодаря Oli для сокращенного regex):
< inputfile perl -pe 's/^(.*)\^/\U\1\E/' > out
Разбивка команда № 1:
< inputfile
: перенаправляет содержание inputfile
кому: stdin
-r
: позволяет использование расширенного regexes> out
: перенаправляет содержание stdout
кому: out
Разбивка команда № 2:
< inputfile
: перенаправляет содержание inputfile
кому: stdin
> out
: перенаправляет содержание stdout
кому: out
Разбивка Regex:
s
: выполняет замену/
: запускает regex^
: соответствует запуску строки(
: запускает первую группу фиксации.*
: соответствия любое количество символов)
: останавливает первую группу фиксации\^
: соответствия a ^
символ/
: останавливается regex / запускает замену\U
: начинает преобразовывать в верхний регистр\1
: замены первой группой фиксации\E
: преобразование остановок в верхний регистр/
: останавливает заменуПравить
Таким образом, после приблизительно час и половина, я придумал это:
awk -F' ' '{ gsub(/\^/,"@ "); for (i=1;i<=NF;i++){ if($i ~ /\@/) $i = toupper($i);};gsub("@ ","");gsub("@",""); print } ' removecharsfile
Основные идеи:
Возможно, лучший подход к записи всего этого на одной строке должен поместить его в файл (аккуратно организованный рев) и выполнить это с awk как так awk -f awkscript theinputfile
# awk script to capitalize
# whatever comes before caret(^)
{
gsub (/\^/, "@ ");
for (i = 1; i <= NF; i++)
{
if ($i ~ /\@/)
$i = toupper ($i);
};
gsub ("@ ", "");
gsub ("@", "");
print
}
И здесь это в действии:
ИСХОДНОЕ СООБЩЕНИЕ
Я внесу свою собственную версию кода с awk:
awk -F'^' '{print toupper($1)$2}' thefile
И конечно можно перенаправить вывод с > output.txt
И здесь это в действии:
Через python3,
Без использования re
модуль,
with open(file) as f:
for line in f:
if '^' in line:
m = line.strip().split('^')
print(m[0].upper() + m[1])
else:
print(line, end="")
С использованием re
модуль.
import re
with open(file) as f:
for line in f:
print(re.sub(r'(.*)\^', lambda m: m.group(1).upper(), line.strip()))
Замена file
в вышеупомянутых сценариях с фактическим путем к файлу. И выполненный использование сценария python3
команда.
Используя vim
:
vim -es '+g/\^/normal gUf^' +wq foo
-es
включает почтенное исключая режимом и заставляет энергию замолчать (главным образом).+
используется для обеспечения команд энергии как параметров командной строки.g/\^/
- выполните команду на всем соответствии строк /\^/
normal
- выполненная остальная часть команды как нормальное действие режима.gUf^
- преобразуйте в верхний регистр (gU
) до ^
(f^
). При использовании диапазона g/.../
в этом случае), курсор установлен в начале каждой строки прежде, чем выполнить команду.wq
).f
ищет первое ^
, так строки с несколькими ^
имел бы только поле преобразованным. Нет никакого простого движения для нахождения последнего ^
. Можно попытаться идти в конец строки и искать назад ($F^
), но это перестало бы работать если ^
последний знак. Так, необходимо было бы сделать это на двух шагах:
vim -es '+g/\^./norm $F^gU0' '+g/\^$/norm gU$' +wq foo
Я установил бы ^
как разделитель полей в awk
в верхнем регистре первое поле:
$ awk 'BEGIN{FS="^"; OFS=""} NF>1{$1=toupper($1)}1' file
FOObar
BArfoo
oofrab
RABOOF
Путем высказывания OFS=""
мы устанавливаем выходного разделителя полей на пустую строку, так, чтобы эти ^
был удален. Если бы это не нужно, awk -F"^" '{$1=toupper($1)}1' file
один сделал бы его; это преобразовывает весь ^
в пробелы.
Примечание мы используем NF>1
для выполнения верхнего регистра в случае, если существует по крайней мере один ^
.
Другой python
подход:
#!/usr/bin/env python2
with open('/path/to/file.txt') as f:
for line in f:
if '^' in line:
index = line.find('^')
print line[:index].upper() + line[index+1:].rstrip()
else:
print line.rstrip()
Вывод:
FOObar
BArfoo
oofrab
RABOOF
index = line.find('^')
содержит индекс символа ^
line[:index].upper()
печатает символы прежде index
(^
) в верхнем регистре (upper()
)
line[index+1:]
печатает символы после ^
буквально
rstrip()
удалит запаздывающие новые строки, добавленные print
по умолчанию.
РЕДАКТИРОВАНИЕ:
Теперь, если у Вас есть файл как это (несколько ^
) :
foo^bar^spam
ba^rfoo^egg
oofrab
raboof^spamegg
и Вы хотите сделать его как:
FOOBARspam
BARFOOegg
oofrab
RABOOFspamegg
В этом случае можно использовать:
#!/usr/bin/env python2
with open('/path/to/file.txt') as f:
for line in f:
if '^' in line:
index = line.rfind('^')
print line[:index].upper().replace('^', '') + line[index+1:].rstrip()
else:
print line.rstrip()
Вывод:
FOOBARspam
BARFOOegg
oofrab
RABOOFspamegg
Только замены rfind('^')
вместо find('^')
, который найдет индекс самых правых ^
и replace('^', '')
заменит все ^
s с пробелами.
Другой awk
версия:
awk '{ a=$_; ismatch=sub(/\^.*/, "", a); b=gensub(/.*\^(.*)/, "\\1", "", $_); if(ismatch==1) { print toupper(a) b} else { print b} }' testdata
человекочитаемый ;)
awk '{
a=$_;
ismatch=sub(/\^.*/, "", a);
b=gensub(/.*\^(.*)/, "\\1", "", $_);
if(ismatch==1) {
print toupper(a) b
}
else {
print b
}
}' testdata
Bash может также сделать это, таким образом, я брошу ответ удара в соединение.
#bash
while IFS= read -r line; do
if [[ $line = *^* ]]; then
tmp=${line%%^*}
line=${tmp^^}${line#*^}
fi
printf '%s\n' "$line"
done < inputfile > outptufile
Это просто выполняет итерации inputfile линию за линией ( BashFAQ 1) и использует расширения параметра, чтобы сделать разделение и uppercasing ( BashFAQ 73).