Переименование файла в bash, используя регулярные выражения

Не большая разница в результате для внешних команд. Выполнение envпросто включает дополнительный execдля выполнения синтаксического анализа присваивания переменной, который в противном случае выполняла бы оболочка. env -iбыл бы более полезен, так как он очищает среду, что не так просто сделать в оболочке.

В обоих случаях расширения, такие как подстановка команд VAR=$(somecmd), выполняются оболочкой до того, как произойдут назначения, и оба случая следуют за PATHи т. д. Единственное различие, которое я могу придумать, это значение _, который Bash устанавливает в имя команды, которую он запускает (, но envнет ). Конечно, без envвы также можете запустить встроенную версию команды оболочки.

8
24.02.2020, 15:09
4 ответа

Здесь вам не нужен rename, вы можете обойти это:

$ file=35554842200284685106000166550020003504201637715423.xml
$ newname=$(sed -E 's/.*(.{48})/\1/'<<<"$file"); 
$ mv -v "$file" "$newname"
renamed '35554842200284685106000166550020003504201637715423.xml' -> '42200284685106000166550020003504201637715423.xml'
18
28.04.2021, 23:22

Вот пример, использующий специфичный для bash P.E. расширение параметра.

file=35554842200284685106000166550020003504201637715423.xml

Только mv для внешних инструментов

mv -v "$file" "${file:6}"

Выход

renamed '35554842200284685106000166550020003504201637715423.xml' -> '42200284685106000166550020003504201637715423.xml'

Сохранение последних 48 символов было бы.

mv -v "$file" "${file:(-48)}"
15
28.04.2021, 23:22
file=35554842200284685106000166550020003504201637715423.xml
rename  "s/"$file"/"${file: -48}"/" *.xml

rename --version:

/usr/bin/rename using File::Rename version 1.10
2
28.04.2021, 23:22

Ваш renameкажется бесполезным из util-linux.

Если вы хотите использовать регулярные выражения, вам следует убедиться, что вместо ((называемогоprename)установлен один из вариантов на основе perl -. А потом:

rename -n 's:^\./\d+(?=\d{44}\.xml\Z)::'./*.xml

(здесь заменяет ваши 48 символов на 44 цифры, за которыми следует .xml, чтобы быть более конкретным ).

В качестве альтернативы вы можете использовать zsh'szmv:

autoload zmv
zmv -n '[0-9]##([0-9](#c44).xml)' '$1'

Или

zmv -n '<->.xml~^?(#c48)' '$f[-48,-1]'

(снять-n(пробный запуск -прогнать ), чтобы сделать это ).

Преимущество этого преимущества заключается в защите от конфликтов (двух файлов с одинаковым именем назначения)

С помощью bashвы можете сделать что-то вроде:

shopt -s extglob nullglob
for f in +([[:digit:]]).xml; do
  ((${#f) <= 48)) || echo mv -i -- "$f" "${f: -48}"
done
9
28.04.2021, 23:22

Теги

Похожие вопросы