Наш офис использует Dropbox на Mac для организации наших дизайнерских проектов. В течение нескольких лет многие из этих файлов и папок сохранялись с символами, которые запрещены в ОС Windows. У нас есть несколько компьютеров с ОС Windows, которые мы должны добавить в наш офис. Это создало проблему, поскольку ни один из этих файлов не синхронизируется должным образом.

Я очень мало знаю о запуске скриптов OSX, но наткнулся на это руководство, которое почти делает то, что мне нужно, за исключением того, что оно мне нужно для работы со всеми подпапками и файлами. Человек создал скрипт automator, завернутый в программу.

Удалить все недопустимые символы из всех имен файлов в данной папке

Возможно ли, чтобы такой скрипт включал все подпапки и файлы? Этот скрипт удаляет все пробелы и специальные символы, но ЗАМЕНА их подчеркиванием была бы намного лучше, если бы это было возможно.

Спасибо

1 ответ1

0
  • Простой способ получить скрипт slhck для рекурсивного поиска в подпапках и файлах, если вы используете bash, - это добавить shopt -s globstar а затем изменить * на ** .  Это не будет работать правильно, если у вас есть каталоги с «нелегальными» символами в их именах.  Вы можете обойти это, просто запустив скрипт n+1 раз, где n - максимальное количество каталогов с недопустимыми символами в любом пути.  Например, если у вас есть каталог f@cat каталогом dog# и fox! каталог ниже, вам нужно будет запустить скрипт четыре раза.

    Я даю лучший способ сделать это ниже.

  • Сценарий slhck действительно должен сказать mv -i вместо mv . Если у вас есть файлы с именами, скажем, cost+tax и cost-tax , скрипт переименует их оба в costtax (или cost_tax , после того как мы внесем это изменение).  Это закроет первый файл вторым файлом.  Опция -i (i nteractive) заставит mv запросить подтверждение.  Вам придется обрабатывать такие столкновения, как это вручную.
  • Чтобы заменить «недопустимые» символы подчеркиванием, замените ${file//[^0-9A-Za-z.]} ${file//[^0-9A-Za-z.]/_} (или, что еще лучше, ${file//[^0-9A-Za-z._]/_}).

Таким образом, с учетом вышеуказанных изменений, сценарий slhck становится

shopt -s globstar
for f in "$1"/**
do
  dir="$(dirname "$f")"
  file="$(basename "$f")"
  mv -i -- "$f" "${dir}/${file//[^0-9A-Za-z._]/_}"
done

При выполнении этого, быть абсолютно уверены, что указать аргумент (например,).; в противном случае он попытается переименовать все файлы в файловой системе (начиная с .).  Вы, вероятно, должны поместить что-то в скрипт, чтобы убедиться, что аргумент / не равен нулю.


Это имеет проблемы с каталогами с недопустимыми символами в их именах, потому что ** расширяется до списка всех файлов и каталогов в поддереве ниже $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" "${dir}/${file//[^0-9A-Za-z.]/_}"; done' sh {} +

Опция -depth для find заставляет его смотреть на ветви каталогов в порядке снизу вверх.  Директива -name заставляет смотреть только имена файлов, которые нужно переименовать.  (Другой скрипт выдаст сообщения об ошибках, когда попытается переименовать файлы для себя, потому что в их именах нет недопустимых символов.)  Затем find передает имена в оболочку, которая выполняет те же действия, что и скрипт, но одной командой.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .