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

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

Я немного в этом понимаю. Следующая команда удаляет пробелы из всех имен файлов.

find . -type f -name "* *.*" -exec bash -c 'mv "$0" "${0// /}"' {} \;

Я бы хотел также удалить запятые, точки и скобки (   ,  ,,  .,  ( и  ) ), но я не знаю, где в команде поместить символы, которые я хочу удалить.

решение1

Короткий ответ: команда для удаления пробелов, запятых, точек и скобок из имени файла (в  $0) —

mv "$0" "${0//[ ,.()]/}"

Но не используйте это…

Более развернутый ответ:

  • Ваша findкоманда говорит -name "* *.*". Это выбирает файлы, имена которых содержат хотя бы один пробел за которым следует по крайней мере одна точка.  Имеет смысл не пытаться обрабатывать файлы, имена которых не содержат пробелов, поскольку если пробелов нет, то и удалять нечего. Но я не знаю, почему эта команда проверяет период. Она переименует fat cat.txtв fatcat.txt, но оставит hot dogи frank.fur terнетронутыми.

    Поскольку вы хотите переименовать файлы, содержащие точки в именах (удалить точки), вам следует изменить свой -nameтест на  -name "*[ ,.()]*".

  • Когда вы имеете дело с именами файлов, которые заранее неизвестны, лучше всего ставить  --перед первым именем файла. Можно утверждать, что это не является строго необходимым, когда вы делаете find . … -exec …, но это хорошая привычка, которую стоит выработать.

  • Если у вас есть файлы с именами fat cat.txtи f a t c a t.txt, они оба будут переименованы в fatcat.txt, и второй из них затрет первый. Передача -nпараметра (no-clobber) mv предотвратит это. Но будьте осторожны: он оставит файлы с пробелами (и т. д.) в своих именах, и он может даже не сообщить вам, что возникла проблема!

  • Ваша текущая команда вызывает новый bashпроцесс для каждого файла. Это может сделать его более длительным, чем необходимо. Лучше вызвать bashодин раз, а затем вызывать mvнесколько раз. Итак, включив все вышесказанное, мы имеем

    find . -type f -name "*[ ,.()]*" -exec bash -c 'mv -n -- "$1" "${1//[ ,.()/}"' sh {} +
    

    Но подождите! Мы еще не закончили! Не используйте вышеперечисленное.

  • При findвыполнении команды (с  -exec), она передает путь к файлу команде. Если у вас есть файл, вызванный fat cat.txtв вашем текущем каталоге, findпередаст ./fat cat.txtкоманде bash. Приведенная выше команда попытается переименовать fat cat.txt( ./fat cat.txt) в  /fatcattxt. Если вы работаете как root (т. е.  sudo), это переместит ваши файлы в корневой каталог, что приведет к большому беспорядку. (Урок: не запускайте команды под учетной записью, sudoесли вы не уверены, что это вам нужно.) Если вы работаете не как root, «хорошая новость» в том, что команда ничего не сделает.

    Итак, теперь, сложив все вместе, мы получаем

    find . -type f -name "*[ ,.()]*" -exec bash -c 'for f do dir="$(dirname "$f")"; base="$(basename "$f")"; echo mv -n -- "$f" "$dir/${base//[ ,.()]}"; done' sh {} +
    

    Обратите внимание, что я включил echoкоманду выше, как меру «посмотри, прежде чем прыгать». Если вы запустите команду выше, она покажет вам все mvнеобходимые команды. Если вам все кажется правильным, запустите команду еще раз, удалив « echo».


Кстати, команда, которую вы показываете в вопросе, не будет выполнена, если какие-либо файлы с расширением .в их имени находятся в каталоге, в имени которого есть пробел.

Связанный контент