Использование расширения параметра оболочки
$ for f in *.log; do g="${f/#file_/}"; echo mv -- "$f" "files_${g%%_*}.log"; done
mv -- file_948_of_2000_push_data_12345.log files_948.log
mv -- file_950_of_2000_push_data_12345.log files_950.log
Использование основанного на perl prename
или команды переименования
$ prename -n -- 's/^(.*?)_(.*?)_.*\.log$/$1s_$2.log/' *.log
file_948_of_2000_push_data_12345.log renamed as files_948.log
file_950_of_2000_push_data_12345.log renamed as files_950.log
Использование mmv
$ mmv -n '*_*_*.log' '#1s_#2.log'
file_948_of_2000_push_data_12345.log -> files_948.log
file_950_of_2000_push_data_12345.log -> files_950.log
Удалите -n
или echo
в зависимости от ситуации.
Sed может справиться с этим довольно легко. Это единственная команда «подстановки» с префиксом диапазона адресов. Я добавил дополнительный интервал для лучшей читаемости:
sed -e '/^\[ABC\]$/ , /^\[.*\]$/ s/^\(value1=\).*$/\1notbla/'
Без дополнительного интервала это:
sed -e '/^\[ABC\]$/,/^\[.*\]$/s/^\(value1=\).*$/\1notbla/'
Вам действительно не нужны привязанные регулярные выражения, но они могут быть более безопасными в некоторых случаях необычного ввода. Немного более короткая версия с незакрепленными регулярными выражениями:
sed -e '/\[ABC\]/,/^\[/s/^\(value1=\).*$/\1notbla/'
Вы просили объяснить каждый флаг или параметр, и у меня есть время, так что готово. Я объясняю последнюю (самую короткую) версию из трех перечисленных выше команд Sed.
Первая часть строки - это диапазон адресов: / startregex /, / stopregex /
Команда s
ubstitute, которая следует за диапазоном адресов, применяется только к строкам из от startregex
до stopregex
(включительно).
В этом случае начальное регулярное выражение - / \ [ABC \] /
. Квадратные скобки обычно являются специальными символами в регулярном выражении, поэтому мы ставим перед каждым символом обратную косую черту, чтобы обозначить буквальные символы квадратных скобок.
Регулярное выражение остановки - / ^ \ [/
, которое использует специальный символ регулярного выражения ^
для обозначения начала строки. Этот шаблон будет соответствовать любой строке, которая начинается с буквальной левой квадратной скобки ( [
).
Команда s
ubstitute в основном довольно проста; общий формат - s / findregex / replacetext /
. Он также может иметь специальные флаги, помещенные после последнего /
, чтобы изменить его поведение, но я здесь не использую никаких таких флагов.
«Найти регулярное выражение»: ^ \ (value1 = \). * $
.
Каретка ( ^
) соответствует началу строки, как упоминалось ранее, а знак доллара ( $
) соответствует концу строки. Таким образом, весь этот шаблон должен соответствовать всей строке, а не только ее части.
Скобки ( ()
), в отличие от квадратных скобок, по умолчанию в регулярных выражениях являются не -специальными, поэтому мы помещаем перед ними обратную косую черту, чтобы придать им особое значение. Они позволяют использовать части совпадающего текста (текст, совпадающий с "регулярным выражением поиска") в заменяющем тексте. В частности, \ 1
в тексте замены означает: «Текст соответствует первому набору круглых скобок в регулярном выражении». В данном случае это всегда просто «значение1 =».
Последний элемент в «регулярном выражении поиска» - . *
. Точка (.
) означает «любой отдельный символ», а звездочка ( *
) означает «любое количество раз (ноль или более)». Итак, точка-звезда (.*
) соответствует всей остальной части строки после знака равенства.
«notbla» в замещающем тексте - это просто статический текст, ничего особенного в этом нет.
Чтобы по-настоящему изучить Sed, я настоятельно рекомендую Grymoire Sed tutorial , который доступен бесплатно в Интернете.
другое решение awk
$ cat ip.txt
[ABC]
value1=bla
value2=bla
value3=bla
[XYZ]
value1=bla
value2=bla
value3=bla
Если строка начинается с [
, назначьте флаг, который будет установлен или сброшен в зависимости от имени блока. Затем, если флаг установлен, выполните замену
$ awk '/^\[/{f=/\[ABC\]/} f{sub("value1=bla","value1=nobla")} 1' ip.txt
[ABC]
value1=nobla
value2=bla
value3=bla
[XYZ]
value1=bla
value2=bla
value3=bla
Аналогичное решение в perl
, замените замену для демонстрации
$ perl -pe '$f=/\[ABC\]/ if /^\[/; s/value2=bla/value2=nobla/ if $f;' ip.txt
[ABC]
value1=bla
value2=nobla
value3=bla
[XYZ]
value1=bla
value2=bla
value3=bla
Если все справа от =
должно быть изменено независимо от В частности, соответствующий bla
, используйте
awk '/^\[/{f=/\[ABC\]/} f{sub(/value1=.*/,"value1=nobla")} 1' ip.txt
perl -pe '$f=/\[ABC\]/ if /^\[/; s/value2=.*/value2=nobla/ if $f;' ip.txt
awk '
BEGIN {FS=OFS="=";}
/\[.*\]/ {if ($0 == "[ABC]") edit=1; else edit=0;}
{if (edit && $1 == "value1" ) $2="notbla";}1
' file