Попробуйте:
find /Users/Chris/CDs -type f -name "*_*" -execdir bash -c 'mv -i -- "$1" "${1//_/}"' Mover {} \;
Как это работает:
-execdir bash -c '...' Mover {} \;
Это запускает bash и говорит ему выполнить команду в одинарных кавычках с Mover
, присвоенным $0
и именем файла, присвоенным $1
.
mv -i -- "$1" "${1//_/}"
Переименовывает файл $1
. При этом используется функция расширения параметров bash, ${1//_/}
, для создания целевого имени из $1
путем удаления всех подчеркиваний.
Опция -i
говорит mv
, что нужно интерактивно спрашивать перед перезаписью файла.
Опция --
сообщает mv
, что больше нет опций. Это необходимо для правильной обработки файлов, имена которых начинаются с -
.
Пример
Начнем с каталога с этими файлами:
$ ls
1_2_3_4 a_b c_d
Далее мы запускаем нашу команду:
$ find . -type f -name "*_*" -execdir bash -c 'mv -i -- "$1" "${1//_}"' Mover {} \;
После завершения команды файлы:
$ ls
1234 ab cd
Цель $0
Обратите внимание на эту команду, где мы добавили ошибку:
$ find . -type f -name "*_*" -execdir bash -c 'foobar -i -- "$1" "${1//_}"' Mover {} \;
Mover: foobar: command not found
Обратите внимание, что Mover
появляется в начале сообщения об ошибке. Это говорит о том, что ошибка происходит из команды bash -c
.
Если мы заменим Mover
на -
, мы увидим:
$ find . -type f -name "*_*" -execdir bash -c 'foobar -i -- "$1" "${1//_}"' - {} \;
-: foobar: command not found
При запуске одной команды в терминале источник ошибки все равно может быть очевиден. Если бы эта команда find
была скрыта в длинном скрипте, то использование более описательного $0
, например Mover
или чего-то еще, могло бы помочь.