У меня есть сотни папок с тысячами подкаталогов и файлов внутри них. Имена файлов в настоящее время имеют формат
sf{number}-{number} - {text}
и мне нужно удалить все до {текст}.
Пример:
sf012-05 - toto - africa.cdg
sf012-05 - toto - africa.mp3
->
toto - africa.cdg
toto - africa.mp3
Дополнительные форматы:
SF-108 - 02 Johnny Hates Jazz Shattered Dreams[K].cdg
02 - David Essex - Rock On.cdg
SF0504 - 13 Walker Brothers, The Make It Easy On Yourself.cdg
SFLY 051 - 07 America A Horse With No Name.cdg
SF217-12 this love - maroon 5.cdg
SF262-13. Same Mistake - James Blunt.cdg
SF287 - 13 Luke Bryan Do I.cdg
SF355-01-15 - Tough Love - Pony.cdg
Track 11 Livin' La Vida Loca (Radio Edit) - Martin, Ricky.cdg
Sunfly Hits 275 - 07 SF275-7-Right Now (Na Na Na)-Akon.mp3
Second, Minute Or Hour - Jack Penate.mp3
SF057 - Karaoke Classics Vol.57 - 03 Abba Thank You For The Music.cdg
особенно последний - полная чушь.
Это значит, что мне нужен рекурсивный скрипт bash regex или что-то подобное, чтобы пройти по этим файлам и переименовать их.
решение1
Если у вас есть утилита на основе Perl rename
(вызывается prename
в некоторых дистрибутивах), вы можете использовать регулярное выражение, чтобы переименовать все файлы за один раз.
Ваше требование требует удаления, sf{number}-{number}
но все примеры начинаются с заглавных букв, некоторые из них содержат только один {number}
, {number}-{number}-{number}
или даже {number}{space}-{space}{number}
. Я предполагаю, что вы хотите включить первые два из этих случаев.
rename -n 's/^sf[0-9-]+\s+(-\s+)?//' [Ss][Ff]*
Удалите , -n
когда будете готовы применить изменения, или измените его на , -v
чтобы увидеть, как он обрабатывает файлы по мере их поступления.
решение2
Самый простой инструмент здесь —зш(как bash, только лучше), с егопричудливое подстановочное словоиzmv
функция. Запустите это из каталога верхнего уровня, в котором вы хотите переименовать файлы.
autoload -U zmv
zmv '(**/)[Ss][Ff][0-9]##-[0-9]##[- ]#(*)' '$1$2'
Объяснение: **/
любая строка ведущих каталогов. Затем идет шаблон sf
(без учета регистра), за которым следуют одна или несколько цифр, тире и еще одно число, за которыми следуют тире и пробелы. Наконец, может быть любой суффикс *
. Цифры в замене относятся к группам в скобках в шаблоне.
В качестве альтернативы вы можете использовать prename
(скрипт переименования на основе Perl, доступный в Debian и Arch Linux, может потребоваться отдельная установка в других дистрибутивах). Вам нужно будет объединить его с , find
чтобы собрать список файлов для переименования. Неважно, если rename
переданы несоответствующие файлы, он пропустит файлы, для которых нет необходимости в переименовании.
find -name '[Ss][Ff]*' -exec prename 's!/!sf[0-9]+-[0-9]+[- ]*!!i' {} +
решение3
Вот код (замените каталог на основной каталог или на тот, где у вас находятся подкаталоги):
cd directory
find -type f | while IFS= read - file; do
name=$(echo "$file" | rev | cut -d'/' -f1 | rev | cut -d'-' -f3- | cut -d' ' -f2-)
path=$(dirname "$file")
newname="${path}/${name}"
echo mv "$file" "$newname"
done
Где каталог — это главный каталог, в котором находятся все подкаталоги....
Пожалуйста, не удаляйте «echo» из «mv», сначала проверьте.
Будьте осторожны и не запустите его в неправильном каталоге, это может быть очень опасно.
решение4
Ты говоришь, что тынужно все удалить до {текст}, но ваш пример этого не показывает. Вместо того, чтобы показывать точный код, позвольте мне просто предложить план.
1) Напишите скрипт, который делает то, что вам нужноодинfilename. Что-то вроде этого может подойти:
#! /bin/sh
test -d ~/OK/${PWD} || mkdir -p ~/OK/${PWD}
ln "$1" "~/OK/${PWD}/$1"
echo "$1" | awk -F ' - ' '{print $NF}'
Это разбивает имя на шаблоне ' - ' и печатает последнее поле. И сохраняет исходное имя файла, чтобы вы могли восстановить его, если что-то пойдет не так. Проверьте это несколько раз и используйте mv
для восстановления имен.
2) Вызовите свой скрипт с помощьюнаходить:
$ find dirname -exec script.awk {} +
Это похоронит вашу машину со множеством параллельных вызовов вашего скрипта. Когда это будет сделано, у вас будет куча ОК-каталогов для удаления, и вы будете знать, как использовать find для их удаления.