Вопрос или проблема
Я запускаю следующую команду, чтобы рекурсивно избавиться от символов в папках, которые создают проблемы с определенными приложениями, скриптами или на NFS/SMB, т.е. заменяю '
на ’
, ?
на ?
(китайский символ), :
на :
(китайский символ) и т.д.
$ find . -type d -execdir /usr/local/bin/rename "s/'/’/g" '{}' +
(rename
— это perl-скрипт Аристотеля Пагалтиса)
Проблема в том, что если данный путь имеет два или более вхождений указанных символов на двух разных уровнях, не получается внести изменения во второй раз, так как исходный путь больше не существует, например, в /data/videos/john's pics/folder/last year's bday/folder/
возникает ошибка No such file or directory.
, потому что там два '
.
Я думаю запустить вышеуказанную команду find
рекурсивно снизу вверх, но не знаю, как это сделать и является ли это лучшим подходом.
Использование find
или любых других утилит/скриптов nix, таких как awk
и т.д., меня устраивает.
Предполагая использование GNU findutils, используйте опцию -depth
у ‘find’, чтобы выводить подкаталоги перед родительской директорией.
Ответ или решение
Для решения вашей задачи по рекурсивному изменению имен директорий в Linux с использованием команды find
, следует использовать ключ -depth
. Этот ключ гарантирует, что поддиректории будут обрабатываться перед их родительскими директориями. Это действительно поможет избежать ошибок, связанных с отсутствием директорий, если в их путях будут находиться символы, требующие замены.
1. Основная концепция
При использовании команды find
с ключом -depth
, вы указываете системным утилитам обрабатывать содержимое каталогов перед тем, как перейти к их родителям. Это означает, что вы сможете вносить изменения в каталоги, находящиеся на нижних уровнях структуры каталогов, не вызывая ошибок, связанных с изменениями на более высоких уровнях.
2. Пример команды
Ваш оригинальный запрос можно адаптировать следующим образом:
find . -depth -type d -execdir /usr/local/bin/rename 's/'\'/'’/g' '{}' +
3. Расшифровка команды
find .
– искать начиная с текущего каталога.-depth
– обработка содержимого директорий перед директорией самой.-type d
– фильтр для обработки только директорий.-execdir
– выполнение команды в директории, где найден объект (в данном случае, директория)./usr/local/bin/rename
– утилита для изменения имен файлов.'s/'\'/'’/g'
– регулярное выражение для замены символа'
на’
. Обратите внимание на экранирование кавычек.'{}'
+ – подстановка имени найденной директории в команду.
4. Дополнительные замены
Если вам необходимо произвести множественные замены в одном проходе, вы можете объединить выражения в одном вызове rename
с использованием Perl:
find . -depth -type d -execdir /usr/local/bin/rename 's/'\'/'’/g; s/\?/\UFF1F/g; s/:/\UFF1A/g' '{}' +
В этом примере \UFF1F
и \UFF1A
представляют собой соответствующие китайские замены для ?
и :
. Вы можете адаптировать это для любых других символов, которые вам необходимо заменить.
5. Проверка результатов
После выполнения команды проверьте изменения, используя команду find
для вывода списка всех директорий:
find .
Это позволит вам убедиться в корректности замен.
Заключение
Использование ключа -depth
в сочетании с утилитой rename
обеспечивает безопасность и надежность при внесении изменений в структуру каталогов, предотвращая ошибки, связанные с отсутствующими директориями. Этот подход является эффективным и оптимизированным решением для вашей задачи по очистке имен директорий от нежелательных символов.