Пакетное переименование, добавьте лишние "." символ в позиции 3 в имени файла, рекурсивно
Я изо всех сил пытался сделать эту работу, но я не очень хорошо с регулярным выражением. Это то, что я пытался сделать, и это не сработало (через 50 минут все еще продолжалось без видимых изменений):
while IFS= read -r -d '' file; do mv $file ${file:0:2}.${file:2}; done
Заранее спасибо!
3 ответа
Одна проблема, с которой вам придется столкнуться при рекурсивном переименовании файлов в каталогах, - это отделение имени файла (которое вы хотите изменить) от пути. Вы не можете просто удалить компонент пути, потому что тогда ваши файлы будут перемещены, а не просто переименованы.
Чтобы использовать ваш оригинальный метод, я думаю, вам нужно сделать что-то вроде
while read -r -d '' f; do
file="${f##*/}"; path="${f%/*}"
echo mv -- "$path/$file" "$path/${file:0:2}"."${file:2}"
done < <(find -type f -iname "*.wav" -print0)
Другой вариант заключается в использовании find командования -execdir вместо -exec, Я думаю, можно с уверенностью предположить, что результаты будут представлены вашей команде переименования (используете ли вы rename или же mv) только с ведущим ./ как путь, и в этом случае вы можете сделать
find -type f -iname "*.wav" -execdir rename -nv -- 's|\./..|$&.|' {} +
или используя более перламутровый вариант
find -type f -iname "*.wav" -execdir rename -nv -- 's|\./..\K|.|' {} +
или используя что-то более эквивалентное вашему оригиналу mv подход
find -type f -iname "*.wav" -execdir bash -c 'echo mv -- "$0" "${0:0:4}"."${0:4}"' {} \;
(обратите внимание, что индексы подстроки были увеличены на 2, чтобы учесть ведущие ./ компонент пути).
Если ваша версия find не имеет -execdir вариант, вы можете изменить rename регулярное выражение, чтобы пропустить самый длинный совпадающий префикс пути, например
find -type f -iname "*.wav" -exec rename -nv -- 's|.*/..\K|.|' {} +
Примечание: во всех этих выражениях есть переключатели no-op (либо переименуйте -n вариант или echo команда), чтобы вы могли проверить, что они будут делать до совершения.
Это работает (проверено):
#!/bin/bash
filenames=$(find . -type f) # stores all filenames in $filenames
for filename in $filenames; do # for each member in $filenames
newfilename=$(echo "$filename" | sed 's/\(.*\)\/\(..\)\(.*\)$/\1\/\2\.\3/') # edits $filename by adding a . after the second character and stores the edited string in $newfilename
mv "$filename" "$newfilename" # renames $filename to $newfilename
done
Это можно легко сделать, используя rename:
rename 's/ /\./' file.txt
Пример:
$ ls -l
-rw-rw-r-- 1 user user 0 Mar 30 04:22 01 Song Title.flac
$ rename 's/ /\./' 01\ Song\ Title.flac
$ ls -l
-rw-rw-r-- 1 user user 0 Mar 30 04:22 01.Song Title.flac
РЕДАКТИРОВАТЬ: Если вы хотите пробел после 01.:
rename 's/ /\. /' file.txt
Если вы хотите, чтобы все файлы в каталоге /directory/to/search и во всех его подкаталогах, имеющих расширение .wav переименуйте, как ожидалось, попробуйте это:
find /directory/to/search -type f -name "*.wav" -execdir rename 's/(^\d+) /$1. /' {} +
Чтобы стать нечувствительным к регистру:
find /directory/to/search -type f -iname "*.wav" -execdir rename 's/(^\d+) /$1. /' {} +