Самый простой способ получить скрипт slhck для рекурсивного поиска в подпапках и файлах, если вы используете bash, - это добавить,
shopt -s globstar
а затем изменить*
на**
. Это не будет работать правильно, если у вас есть каталоги с «нелегальными» символами в их именах. Вы можете обойти это, просто запустив скрипт n +1 раз, где n - максимальное количество каталогов с недопустимыми символами в любом пути. Например, если у вас естьf@cat
каталог,dog#
каталог под ним иfox!
каталог под ним, вам нужно будет запустить сценарий четыре раза.Я даю лучший способ сделать это ниже.
- Сценарий slhck действительно должен сказать
mv -i
вместоmv
. Если у вас есть файлы с именами, скажем,cost+tax
иcost-tax
, сценарий переименует их в обаcosttax
(илиcost_tax
после того, как мы внесем это изменение). Это закроет первый файл вторым файлом.-i
( Я опция Интерактивно) заставитmv
просить подтверждения. Вам придется обрабатывать такие столкновения, как это вручную. - Чтобы заменить «недопустимые» символы подчеркиванием, измените
$
на$
(или, что еще лучше,$
).
Таким образом, с учетом вышеуказанных изменений, сценарий slhck становится
shopt -s globstar for f in "$1"/** do dir="$(dirname "$f")" file="$(basename "$f")" mv -i -- "$f" "$/$" done
При выполнении этого обязательно убедитесь, что вы указали аргумент (например, .
); в противном случае он попытается переименовать все файлы в файловой системе (начиная с /
). Вы, вероятно, должны поместить что-то в скрипт, чтобы убедиться, что $1
аргумент не нулевой.
Это имеет проблемы с каталогами с недопустимыми символами в их именах, потому что **
расширяется до списка всех файлов и каталогов в поддереве $1
с ветвями в порядке сверху вниз. Так что, если есть f@cat/dog#
, то увидим f@cat
и в f@cat/dog#
качестве аргументов. Так это будет переименовать f@cat
в f_cat
, а затем искать f@cat/dog#
- что больше не существует, так как он был переименован в f_cat/dog#
. Мы можем исправить это, сделав
find "$1" -depth -name '*[^0-9A-Za-z._]*' -exec sh -c \ 'for f do dir="$(dirname "$f")"; file="$(basename "$f")"; mv -i -- "$f" "$/$"; done' sh {} +
-depth
Вариант find
говорит, что смотреть на ветви каталогов в снизу-сверху порядка. -name
Директива заставляет его искать только в именах файлов, которые должны быть переименованы. (Другой сценарий выдаст сообщения об ошибках, когда попытается переименовать файлы для себя, поскольку в их именах нет недопустимых символов.) find
Затем эти имена передаются в оболочку, которая выполняет то же действие, что и сценарий, но в виде одной команды. ,