#bash #sed
#bash #sed
Вопрос:
Учитывая следующие входные данные:
task-rest_acq-mb01_bold_magnitude01a.json
task-stroop_acq-mb01_bold_magnitude01a.json
task-rest_acq-mb01_bold_magnitude01.json
task-stroop_acq-mb01_bold_magnitude01.json
task-rest_acq-mb02_bold_magnitude02_e2.json
task-stroop_acq-mb02_bold_magnitude02_e2.json
task-rest_acq-mb03_bold_magnitude03_e3.json
task-stroop_acq-mb03_bold_magnitude03_e3.json
Я хочу следующий вывод:
task-rest_acq-mb01_bold_magnitude01a.json # no change.
task-stroop_acq-mb01_bold_magnitude01a.json # no change
task-rest_acq-mbme01_bold_magnitude01.json # changed acq-mb to acq-mbme
task-stroop_acq-mbme01_bold_magnitude01.json # same as above
task-rest_acq-mbme02_bold_magnitude02.json # same and removed _e2
task-stroop_acq-mbme02_bold_magnitude02.json # same as above
task-rest_acq-mbme03_bold_magnitude03.json # same and removed _e3
task-stroop_acq-mbme03_bold_magnitude03.json # same as above
То есть я хочу выполнить два изменения:
- удалите суффиксы имен, если они присутствуют, например, «_e2», и
- измените имя acq_mb на acq_mbme, если имя файла (без расширения) не заканчивается буквой (в моем примере буквой a).
Я попробовал следующее регулярное выражение в regex101, и оно в точности соответствует тому, что я хочу, и сохраняет информацию в группах захвата, чтобы я мог правильно переименовать свои файлы:
(acq-mb)(.*_bold_magnituded*)([.|_] ed)*.
Поэтому я попытался использовать следующий скрипт для пакетного переименования:
for i in *; do ## /1 /2 /3
mv "$i" "`echo $i | sed "s/(acq-mb)(.*_bold_magnituded*)([.|_] ed)*./acq_mbme2/"`";
done
Я хочу сохранить только группу захвата 2, поэтому я не использую другие группы захвата в строке подстановки.
Проблема в том, что я получаю следующую ошибку при тестировании моего скрипта:
выражение sed: -e # 1, символ 51: недопустимая ссылка 1 на RHS команды `s’
Я хотел бы понять, почему это происходит, и как я могу это исправить, чтобы мое решение работало. (GNU sed 4.2.2)
Спасибо, что нашли время помочь мне.
Редактировать
Окончательное решение (кредиты принятому ответу):
for i in *; do
mv "$i" "`echo $i | sed -r "s/(acq-mb)(.*_bold_magnitude[0-9]*)([.|_] e[0-9])*./acq_mbme2./"`";
done
Комментарии:
1. Вам нужно либо избежать группирующей скобки (
(...)
), либо использоватьsed
-r
флаг расширенного регулярного выражения2. Вы также могли бы рассмотреть возможность использования
rename
команды вместо написания собственного цикла с помощью sed.
Ответ №1:
вот команда sed, которую вы ищете:
sed -r 's/(acq-mb)(.*_bold_magnitude[0-9]*)([.|_] e[0-9])*./acq_mbme2./'
-r
для того, чтобы использовать ()
вместо ()
.
sed
не знает, d
используйте [0-9]
вместо этого.
измените acq_mbme2
acq_mbme2.
, иначе вы получите, например ...magnitude02json