Я хочу переименовать все файлы в каталоге. Новые имена не следуют какой-либо схеме, поэтому я не могу использовать rename
.
Есть ли эффективный способ сделать это, поэтому мне не придется использовать mv foo.txt bar.txt
для каждого файла?
3 ответа
Размышляя о написании этого сценария, я проверил, не заняли ли уже возможные имена, и выяснил, что мое предположение "интерактивный ход" уже написано и готово к использованию. Для большинства систем он должен быть доступен в пакете renameutils, который содержит различные инструменты, которые очень полезны:
- qmv/qcp: Quick Move/Copy, записывает все имена файлов в текстовый файл, который затем можно редактировать.
- imv/icp: Interactive Move/Copy, запрашивает новое имя файлов.
Проблема с imv
/icp
в этом случае заключается в том, что они принимают только один аргумент:
imv FILENAME
Несколько аргументов приведут к ошибке. Таким образом , вы будете в основном должны обернуть его в короткий цикл:
for file in *; do imv "$file"; done
Это, конечно, сложно напечатать, поэтому мы должны обернуть это в готовую к использованию функцию, которую мы можем поместить в наш файл .bashrc
.
# Mass Interactive Move
function mimv {
for file in "$*"; do
imv "$file"
done
}
К счастью, imv
показывает имя файла, который в данный момент обрабатывается, поэтому нам не нужны никакие операторы echo, чтобы мы знали, что происходит.
Вы можете использовать эту команду:
for i in *; do
read -p "$i -> " newname
if [[ ! -z "$newname" ]]; then
mv -v -- "$i" "$newname"
fi
done
Он попросит вас ввести новое имя для каждого файла, а также для каждого каталога (for i in *
) в текущем каталоге. Новое имя читается в $newname
. Если вы нажмете Enter без ввода нового имени, ничего не делается -z $newname
чеки, если $newname
пусто (г !
логично not
), иначе mv
используется для переименования файла.
Если вы хотите немного изменить имя файла, будет эффективнее, если вы сможете отредактировать его, начиная со старого имени файла, как предлагает @grawity:
for i in *; do
read -p "$i -> " -e -i "$i" newname
if [[ ! -z "$newname" ]]; then
mv -v -- "$i" "$newname"
fi
done
Я протестировал его с именами файлов, содержащими пробелы и фигурные скобки, однако, пожалуйста, используйте его на свой страх и риск (и сделайте резервную копию оригинальных файлов раньше).
#!/usr/bin/env bash for files in $( echo * ); do echo -n Rename $files to which name? ; read new_name ; mv "$files" "$new_name"; done