sed
будет работать, но это намного проще с tr
, который переводит символы.
for file in *.php; do tr 'ăâîșțĂÂÎȘȚ' 'aaistaaist' < "${file}" > "translated_${file}"
Эквивалент sed
(который вам понадобится в системах GNU, а не OS / X, где tr
не поддерживает многобайтовые символы) будет:
sed 'y/ăâîșțĂÂÎȘȚ/aaistaaist/'
Если то, что вы пытаетесь сделать, это вывести все, что находится между senderID=
и WaveShow,
включительно, тогда вам нужна эта sed
команда:
sed -n 's/.*\(senderID=.*WaveShow,\).*/\1/p'
Это будет захватывать все, что находится между этими двумя строками, используя квадратные скобки \(
и \)
и выводить их, используя\1
(и \2
и т. д., если у вас есть больше захватов ).
Обратите внимание, что начальный .*
является «жадным», что означает, что если у вас есть строка senderID=
дважды во входных данных, то первая будет отброшена. Если это не то, что вам нужно, то sed
не подходит; perl
справится с этим. Затем команда становится:
perl -ne 'print if s/.*?(senderID=.*WaveShow,).*/$1/'
-n
означает «выполнять цикл для каждой строки ввода и не печатать строку в конце цикла». -e
указывает выражение, которое должно выполняться внутри цикла.
?
после .*
изменяет *
так, чтобы оно совпадало как можно меньше (, т.е. соответствовало не -жадно ). Скобки заставляют Perl сгруппировать эту часть и захватить ее, что затем можно использовать как $1
для первого захвата, $2
для второго и т. д.
Однако это не лучший способ сделать это в perl. Это намного лучше, так как не требует ненужного изменения строк, захвата текста и его печати :
.perl -ne 'print "$1\n" if /(senderID=.*WaveShow,)/'
Вероятно, в perl есть гораздо больше способов сделать это, возможно, даже более эффективно.
Нужна ли запятая в конце?
Если нет, должно работать:
grep senderID filename | cut -d '[' -f 2- | cut -d ',' -f -5
Выход:
senderID=60, ipaddress=/10.1.1.11:8443, serviceIdinList=[13], serviceBitbox=11111, servicesList= | BeatController | BeatMaker | WaveShow