Добавить префикс ко всем изображениям (рекурсивно) - PullRequest
4 голосов
/ 26 мая 2011

У меня есть папка с более чем 5000 изображений, все с расширением JPG.

Я хочу рекурсивно добавить префикс «thumb_» ко всем изображениям.

Iнашел похожий вопрос: Переименовать файлы и каталоги (добавить префикс) , но я хочу добавить префикс только к файлам с расширением JPG.

Ответы [ 7 ]

5 голосов
/ 26 мая 2011

Одно из возможных решений:

find . -name '*.jpg' -printf "'%p' '%h/thumb_%f'\n" | xargs -n2  echo mv

Принсипи: найдите все необходимые файлы и подготовьте аргументы для стандартной команды mv.

Примечания:

  • аргументы для mv заключены в ' для разрешения пробелов в именах файлов.
  • Недостаток: это не будет работать с именами файлов, которые содержат ' апостроф, как многие mp3-файлы.Если вам нужно переместить более странные имена файлов, проверьте ниже.
  • указанная выше команда предназначена для пробного запуска (показывает только команды mv с аргументами).Для реальной работы удалите echo притворяясь mv.

ЛЮБОЕ переименование имени файла.В оболочке нужен разделитель.Проблема в том, что имя файла (хранящееся в переменной оболочки) обычно может содержать сам разделитель, поэтому:

mv $file $newfile         #will fail, if the filename contains space, TAB or newline
mv "$file" "$newfile"     #will fail, if the any of the filenames contains "

правильное решение:

  • подготовить имя файла с правильным экранированием
  • использовать язык сценариев, который легко понимает ЛЮБОЕ имя файла

Подготовка правильного экранирования в bash возможна с его помощьювнутренняя директива форматирования printf и %q = print quoted.Но это решение длинное и скучное.

ИМХО, самый простой способ - использовать perl и дополнить нулями print0, как показано ниже.

find . -name \*.jpg -print0 | perl -MFile::Basename -0nle 'rename $_, dirname($_)."/thumb_".basename($_)'

Выше описано использование возможности perl для манипулированияимена файлов и, наконец, переименовывает файлы.

2 голосов
/ 26 мая 2011

Остерегайтесь имен файлов с пробелами в них (выражение for ... in ... останавливается на них) и имейте в виду, что результат find . ... всегда будет начинаться с ./ (и, следовательно, попытайтесь дать вам такие имена, как thumb_./file.JPG что не совсем правильно).

Поэтому это не тривиальная вещь, чтобы получить право при любых обстоятельствах. Выражение, которое я нашел для правильной работы (с пробелами, подкаталогами и всем этим):

find . -iname \*.JPG -exec bash -c 'mv "$1" "`echo $1 | sed \"s/\(.*\)\//\1\/thumb/\"`"' -- '{}' \;

Даже это может не соответствовать определенным именам (с кавычками) ...

2 голосов
/ 26 мая 2011

Вы можете использовать тот же ответ, просто используйте *.jpg вместо *.

1 голос
/ 19 октября 2013

В OS X 10.8.5 поиск не имеет опции -printf. Похоже, что порт, содержащий переименование, зависел от пакета разработки WebkitGTK, на установку которого уходили часы.

Этот однострочный скрипт рекурсивного переименования файлов работал для меня:

find . -iname "*.jpg"  -print | while read name; do cur_dir=$(dirname "$name"); cur_file=$(basename "$name"); mv "$name" "$cur_dir/thumb_$cur_file"; done

Я на самом деле переименовал файлы просмотра CakePHP с префиксом admin_, чтобы переместить их все в раздел администратора.

1 голос
/ 27 мая 2011

Используйте rename для этого:

rename 's/(\w{1})\.JPG$/thumb_$1\.JPG/' `find . -type f -name *.JPG`
1 голос
/ 26 мая 2011

for file in *.JPG; do mv $file thumb_$file; done

, если несколько уровней каталогов ниже текущего:

for file in $(find . -name '*.JPG'); do mv $file $(dirname $file)/thumb_$(basename $file); doneдоказательство:

jcomeau@intrepid:/tmp$ mkdir test test/a test/a/b test/a/b/c
jcomeau@intrepid:/tmp$ touch test/a/A.JPG test/a/b/B.JPG test/a/b/c/C.JPG
jcomeau@intrepid:/tmp$ cd test
jcomeau@intrepid:/tmp/test$ for file in $(find . -name '*.JPG'); do mv $file $(dirname $file)/thumb_$(basename $file); done
jcomeau@intrepid:/tmp/test$ find .
.
./a
./a/b
./a/b/thumb_B.JPG
./a/b/c
./a/b/c/thumb_C.JPG
./a/thumb_A.JPG
jcomeau@intrepid:/tmp/test$
0 голосов
/ 26 мая 2011

Только для jpg файлов в текущей папке

for f in `ls *.jpg` ; do mv "$f" "PRE_$f" ; done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...