Пакетное переименование файлов с помощью sed. Недопустимая ссылка в `s` команде RHS

#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
  

То есть я хочу выполнить два изменения:

  1. удалите суффиксы имен, если они присутствуют, например, «_e2», и
  2. измените имя 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