Переименование файлов в дереве с расширением, включенным в базовое имя - PullRequest
0 голосов
/ 16 января 2019

У меня есть куча файлов в каталоге (и множество дочерних каталогов) на сервере CentOS, у которых расширение случайно прикреплено к базовому имени, например:

12345jpg

Я хочу переименоватьвсе они к

12345.jpg

Я близок к этой команде, но не могу заставить regex переименовать в работу.

find . -type f ! -name "*.*" -exec rename 's/([0-9]{5})(.*)/$1.$2/'

Обновление: Будет ли этолучше использовать sed вместо rename?Как это?(который также не работает в данный момент)

find . -type f ! -name "*.*" -exec sed -i '' s/([0-9]{5})(.*)/1.2/g {} ;

Ответы [ 2 ]

0 голосов
/ 16 января 2019

Я не думаю, что утилита rename может обрабатывать обратные ссылки.

Вот портативное решение только для posix:

find . -type f -name '[0-9][0-9][0-9][0-9][0-9]?*' \
       -not -name '*.*' |while IFS= read file; do
  dir="${file%/*}"
  file="${file#$dir/}"
  B="${file#?????}"
  A="${file%$B}"
  mv -i "$dir/$file" "$dir/$A.$B"
done

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

Затем он перебирает строку за строкой (да, это будет прерываться, если в именах файлов есть разрыв строки - не делайте этого!). Я явно очищаю $IFS, чтобы пробелы не интерпретировались как разделители полей.

В цикле while я массирую имя файла. Сначала я извлекаю имя каталога (которое равно ./, если его нет; будьте осторожны, если вы отклоняетесь от find . …), а затем изменяю переменную $file, чтобы сохранить только имя файла. Затем я присваиваю $B имени файла, в котором отсутствуют первые пять символов (которые find уже должны быть цифрами), а $A - эти первые пять символов. Теперь мы можем сделать переименование с дополнительной точкой.

Я использовал mv -i в качестве безопасности. Это будет интерактивно спрашивать обо всем, что вы перезаписали, прежде чем сделать это.

0 голосов
/ 16 января 2019

Вы должны правильно выйти из своего регулярного выражения и использовать \1.\2 вместо

s/\([0-9]\{5\}\)\(.*\)/\1.\2/

Например:

$ echo '12345jpg' | sed 's/\([0-9]\{5\}\)\(.*\)/\1.\2/'
12345.jpg
...