Сценарий оболочки для исправления неправильных имен файлов?

Я ИТ в моей маленькой фирме; И, несмотря на мои страшные предупреждения, каждый ставит файлы на сервер с ужасными именами, включая ведущие и конечные пробелы, плохие символы (включая \ ; / + . < > - т. Д.).

Они делают это, обращаясь к серверу FreeBSD / FreeNAS через AFP на компьютерах Mac, поэтому никакая часть системы не жалуется.

Есть ли сценарий, который я могу использовать, чтобы пройти через полное дерево каталогов и исправить неправильные имена файлов?

В основном замените все пробелы и плохие ASCII на _ … и если файл уже существует, просто нажмите « _2 или что-то в конце.

Я не думаю, что есть способ заставить систему обеспечить соблюдение хороших соглашений об именах файлов, не так ли?

Благодаря!

Я бы использовал bash и нашел. Я уверен, что есть более простой вариант, но вот что я придумал:

  1. Это может касаться имен файлов, содержащих «/» (find выдаст предупреждение, проигнорирует его), но он будет работать только с файлами в текущем каталоге (без подкаталогов). Я не мог понять, как сказать bash или найти, чтобы различать «/» в имени файла и «/», который является частью пути.

     for i in $(find . -maxdepth 1 -type f -name "*[\:\;><\@\$\#\&\(\)\?\\\/\%]*" | sed 's/\.\///'); do mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\/\%]/_}; done 
  2. Это не может содержать имена файлов, содержащие «/», но он будет работать со всеми файлами в текущем каталоге и его подкаталогах :

     for i in $(find . -type f -name "*[\:\;\>\<\@\$\#\&\(\)\?\\\%]*"); do mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\%]/_}; done 

Обязательно проверьте их перед запуском . Они отлично работали в нескольких тестах, которые я выполнял, но я не был исчерпывающим. Также имейте в виду, что я на Linux-системе. Конкретная реализация find и, возможно, bash, может отличаться от вашей.


EDIT: Изменение команды mv $i на `mv -i $ i 'заставит mv запросить вас перед перезаписью существующего файла.

EDIT2: Чтобы иметь дело с именами файлов с пробелами, вы можете изменить переменную bash IFS (Input Field Separator) так, как она (адаптирована здесь ):

 SAVEIFS=$IFS; IFS=$(echo -en "\n\b"); for i in $(find . -type f -name "*[\:\;\>\<\@\$\#\&\(\)\?\\\%\ ]*"); do mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\%\ ]/_}; done; IFS=$SAVEIFS 

Я также изменил регулярное выражение для соответствия / замены пробелов символами подчеркивания. Бит SAVEIFS просто возвращает переменную IFS в исходную конфигурацию.


ОБЪЯСНЕНИЕ:

 for i in $(command); do something $i; done 

Это общая петля bash. Он будет проходить через вывод команды, последовательно устанавливая переменную $ i каждому из значений, возвращаемых командой, и будет что-то делать с ней.

 find . -maxdepth 1 -type f -name "*[\:\;><\@\$\#\&\(\)\?\\\/\%]*" ' 

Найдите все файлы в текущем каталоге, имя которого содержит один из следующих символов :;><@$#&()\/% . Чтобы добавить больше, просто избегайте их с помощью «\» (например, «\ ¿») и добавьте их в список в скобках ([]). Вероятно, не все эти символы должны быть экранированы, но я никогда не могу вспомнить, какие специальные переменные в среде, поэтому я избегаю всего, на всякий случай.

 sed 's/\.\/// 

Удалите текущий каталог из вывода find, напечатайте «foo» вместо «./foo».

 mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\/\%]/_} 

Каждый раз, когда эта маленькая петля цикла, $ i будет именем плохо названного файла. Эта команда переместит (переименует) этот файл, изменив все нежелательные символы на «_». Посмотрите на замену bash для получения дополнительной информации.


  • Как вызвать (gui) и использовать пароль root для скрипта?
  • Экран Gnu: выполнить команду при подключении
  • Запустите сценарий в OS X 10.6 при сетевом подключении. (Например, /etc/network/if-up.d/)
  • Странное поведение strace и setuid: разрешение отклонено под strace, но не работает нормально
  • Ssh и shell через ssh: как выйти?
  • Обработка пробелов во имя набора данных ZFS в сценарии оболочки
  • С скриптом оболочки, можно сказать, когда он запускается с помощью cron vs run вручную?
  • Запуск процесса linux в фоновом режиме
  • Запустить сценарий оболочки на OS X без появления окна терминала?
  • Сценарий postinstall для Mac не запущен
  • Сделать pendrive загрузочным через командную строку Ubuntu
  • Давайте будем гением компьютера.