1

Я хотел бы изменить файл с именем, например:

d1-a2_A1_B1.txt
abcd_A90_B2.txt

где я хочу вставить _FOO между первыми _A[0-9]\+ и _B[0-9] чтобы имена файлов становились

d1-a2_A1_FOO_B1.txt
abcd_A90_FOO_B2.txt

Но мое регулярное выражение не работает:

for f in $(ls); do mv $f \`echo $f | sed -e s/\(.*_A[0-9]\+\)\(_B[0-9].*\)/$1_FOO$2/\`; done

Я попробовал с одной строкой:

echo abcd_A90_B2.txt | sed -e s/\(.*_A[0-9]\+\)\(_B[0-9].*\)/$1_FOO$2/

ОК: это сработало:

echo abcd_A90_B2.txt | sed -e 's/\(_A[0-9]\+\)\(_B[0-9]\)/\1_FOO\2/'

2 ответа2

0

Вы можете избежать использования sed и других манипуляций со строками, используя mmv:

$ mmv -m -n  '*_A*_B*.txt' '#1_A#2_FOO_B#3.txt'
abcd_A90_B2.txt -> abcd_A90_FOO_B2.txt
d1-a2_A1_B1.txt -> d1-a2_A1_FOO_B1.txt

(Оставьте -n или замените его на -v чтобы фактически переименовать файлы, как только вы подтвердите, что все файлы сопоставлены и переименованы так, как вы хотите.

0
  • Добавьте параметр -r к sed (чтобы заставить его использовать расширенные регулярные выражения; обычно он не понимает +).
  • Поместите свой sed сценарий в кавычки (предпочтительно одиночные кавычки).
  • Измените $1 и $2 в вашем скрипте на \1 и \2:

    sed -re ' s/(._О [0-9]+)(_ В [0-9])./\1_FOO\2/'

Также,

  • Для ясности, вы можете изменить `…` на $(…) - посмотрите это, это и это - то есть обработайте echo | sed же, как вы справляетесь с ls .
  • Лучше сказать for f in * (а не for f in $(ls)).
  • Вы должны заключать в кавычки переменные оболочки (например, echo "$f"), если у вас нет веских причин не делать этого, и вы уверены, что знаете, что делаете.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .