Напишите простой скрипт, который автоматически переименовывает несколько файлов. В качестве примера мы хотим, чтобы файл * 001.jpg был переименован в определяемую пользователем строку + 001.jpg (например: MyVacation20110725_001.jpg). Этот сценарий используется для того, чтобы фотографии с цифровой камеры имели понятные имена.
Для этого мне нужно написать сценарий оболочки. Может кто-нибудь подсказать, с чего начать?
Пример, который поможет вам оторваться от земли.
для f в *. jpg; do mv "$ f" "$ (echo" $ f "| sed s/IMG/VACATION/)"; готово
В этом примере я предполагаю, что все ваши файлы изображений содержат строку IMG
, и вы хотите заменить IMG
с ОТПУСК
.
Оболочка автоматически оценивает *. jpg
для всех подходящих файлов.
Второй аргумент mv
(новое имя файла) — это результат выполнения команды sed
, которая заменяет IMG
с ОТПУСК
.
Если ваши имена файлов содержат пробелы, обратите особое внимание на "$ f"
обозначение. Вам нужны двойные кавычки, чтобы сохранить пробелы.
Вы можете использовать утилиту rename для переименования нескольких файлов по шаблону. Например, следующая команда добавит строку MyVacation2011_ ко всем файлам с расширением jpg.
переименовать 's/^/MyVacation2011_/g' * .jpg
или
переименовать


-
Но должны быть варианты эти команды, переименование аналогично mv на моем RedHat 6.5 — ixe013, 3 апреля 2015 г., 21:29
-
1У меня это не сработало, потому что e У меня было слишком много файлов:
-bash:/usr/bin/rename: слишком длинный список аргументов
. Но согласен, неплохо, если у вас будет список поменьше — ТМ. 21 ноя. 2015, 17:50 -
8@ ixe013 Это переименование версии Perl, а не встроенной утилиты. Следуйте руководству на stackoverflow.com/questions/22577767/… для установки. — Fruit 23 марта ’16 в 16:32
-
2Проблема «Слишком длинный список аргументов» можно обойти, используя
find
:find. -name * .jpg -exec rename {} ;
Это вызовет переименование один раз для каждого файла. — Эрик Форсберг, 22 ноя 2016, в 12:26 -
1@CpILL он использует группы захвата регулярных выражений, а строка замены будет заменять
$
совпадением. напримерпереименуйте 's/([^- ]+)-([^.pting+)/$ 2- $ 1/g' *
. Шаблон^ ([^ -] +) - ([^.] +)
означает: с начала имени захватить 1 или более символов, которые НЕ являются-
, затем ожидайте тире, затем захватите 1 или несколько символов, не являющихся.
.$ 1
— это первый захват,$ 2
— второй. — erich2k8 18 апр. ’19 в 15:53
Вы можете использовать утилиту rename для переименовать несколько файлов по шаблону. Например, следующая команда добавит строку MyVacation2011_ ко всем файлам с расширением jpg.
переименовать 's/^/MyVacation2011_/g' * .jpg
или
переименовать
для файла в формате * .jpg; сделать mv $ file $ {file//IMG/myVacation}; готово
Снова предполагая, что все ваши файлы изображений имеют строку «IMG», и вы хотите заменить «IMG» на «myVacation».
С помощью bash, вы можете напрямую преобразовать строку с расширением параметра.
Пример: если это файл IMG_327.jpg, команда mv
будет выполняться, как если бы вы выполняли mv IMG_327.jpg myVacation_327.jpg
. И это будет сделано для каждого файла, найденного в каталоге, соответствующем *. Jpg
.
IMG_001.jpg -> myVacation_001.jpg
IMG_002. jpg -> myVacation_002.jpg
IMG_1023.jpg -> myVacation_1023.jpg
и так далее …
-
2это лучший ответ на свете, и он отлично работает на linux/mac! спасибо Kra 05 янв. 2017, в 10:01
-
1@MikeStewart В документации GNU, на которую вы ссылаетесь, представлены многие возможности, не относящиеся к POSIX. См. POSIX.1-2008: § 2.6. 2: Расширение параметров для спецификации POSIX при расширении параметров. Подстановка
$ {file//IMG/myVacation}
в этом ответе не соответствует POSIX. Он не работает стире
. В Debian по умолчанию используетсяsh
dash
. Когдаdash
встречает$ {file//IMG/myVacation}
, он выдает ошибкуПлохая подстановка
, потому что этот синтаксис подстановки не соответствует POSIX. — Сусам Пал 22 сен ’20 в 9:45
для файла в формате * .jpg; сделать mv $ file $ {file//IMG/myVacation}; готово
Снова предполагая, что все ваши файлы изображений имеют строку «IMG», и вы хотите заменить «IMG» на «myVacation».
С помощью bash, вы можете напрямую преобразовать строку с расширением параметра.
Пример: если это файл IMG_327.jpg, команда mv
будет выполняться, как если бы вы выполняли mv IMG_327.jpg myVacation_327.jpg
. И это будет сделано для каждого файла, найденного в каталоге, соответствующем *. Jpg
.
IMG_001.jpg -> myVacation_001.jpg
IMG_002. jpg -> myVacation_002.jpg
IMG_1023.jpg -> myVacation_1023.jpg
и т. д.
В этом примере я предполагаю, что все ваши файлы изображений начинаются с «IMG», и вы хотите заменить «IMG» на «VACATION»
решение: сначала идентифицировали все файлы jpg, а затем заменили ключевое слово
find. -name '* jpg' -exec bash -c 'echo mv $ 0 $ {0/IMG/VACATION}' {} ;
-
4Лучший ответ, поскольку он позволяет обход дерева каталогов, использует встроенные утилиты bash и легко настраивается. Кроме того, в примере дается неразрушающий тест, чтобы убедиться, что изменения верны. — Дэн Мергенс, 15 янв., 21:16
-
5Просто примечание здесь … довольно очевидно, но заслуживает внимания: часть
'echo mv $ 0 $ {0/IMG/VACATION}'
— это фактическая команда, которая запускаться для каждого найденного файла. Итак, если вы оставите тамecho
, он будет отображать только то, что будет делать. Удалите командуecho
, чтобы фактически переместить файлы, например.найти. -name '* jpg' -exec bash -c 'mv $ 0 $ {0/IMG/VACATION}' {} ;
— dmmd 9 мая 2018, в 23:55 -
1Престижность за включение
echo
, чтобы пользователи знали, сработает он или нет — Тан, 21 мар. ’19 в 8: 00
в этом примере я предполагаю, что все ваши файлы изображений начинаются с «IMG», и вы хотите заменить «IMG» на «VACATION»
решение: сначала идентифицировали все файлы jpg, а затем заменили ключевое слово
find. -name '* jpg' -exec bash -c 'echo mv $ 0 $ {0/IMG/VACATION}' {} ;
Другой вариант — :
для i in * 001.jpgdo echo "mv $ i yourstring $ {i # * 001.jpg}" done
удалить echo
после того, как все будет правильно.
Замена параметра на #
сохранит только последнюю часть, поэтому вы может изменить свое имя.
Другой вариант:
для i in * 001.jpgdo echo "mv $ i yourstring $ {i # * 001.jpg} "готово
удалить echo
, когда все будет правильно.
При замене параметра на #
останется только последняя часть, поэтому вы можете изменить ее имя.
найти. -тип f | sed -n "s/ (. * ) factory .py $/& 1service .py/p" | xargs -p -n 2 mv
например, переименует все файлы в cwd с именами, заканчивающимися на «factory.py», которые будут заменены именами, заканчивающимися на «service.py»
объяснение:
1) в sed cmd флаг -n будет подавлять нормальное поведение эха ввода для вывода после применения команды s///и опция p в s///заставит запись выводиться, если сделана подстановка. поскольку подпрограмма будет создана только при совпадении, sed будет выводить только файлы, заканчивающиеся на «factory.py»
2) в строке замены s///мы используем «&» для вставить в замену всю совпадающую строку, за которой следует пробел. из-за этого очень важно, чтобы наш RE соответствовал всему имени файла. после символа пробела мы используем » 1service. py «, чтобы интерполировать строку, которую мы проглотили до» factory.py «, за которой следует» service.py «, заменив ее. Таким образом, для более сложных преобразований вам придется изменить аргументы на s///(при этом re по-прежнему соответствует всему filename)
пример вывода:
foo_factory.py foo_service.pybar_factory.py bar_service.py
3) мы используем xargs с -n 2, чтобы использовать вывод sed 2 строк с разделителями за раз, передавая их в mv (я также добавил туда параметр -p, чтобы вы могли чувствовать себя в безопасности при запуске этого).
найти. -тип f | sed -n "s/ (. * ) factory .py $/& 1service .py/p" | xargs -p -n 2 mv
например, переименует все файлы в cwd с именами, заканчивающимися на «factory.py», которые будут заменены именами, заканчивающимися на «service.py»
объяснение:
1) в sed cmd флаг -n будет подавлять нормальное поведение эха ввода для вывода после применения команды s///и опция p в s///заставит запись выводиться, если сделана подстановка. поскольку подпрограмма будет создана только при совпадении, sed будет выводить только файлы, заканчивающиеся на «factory.py»
2) в строке замены s///мы используем «&» для вставить в замену всю совпадающую строку, за которой следует пробел. из-за этого очень важно, чтобы наш RE соответствовал всему имени файла. после символа пробела мы используем » 1service.py» для интерполяции строки, которую мы проглотили, до «factory.py», за которой следует «service.py», заменяя ее. Поэтому для более сложных преобразований вам необходимо изменить аргументы на s///(при этом re по-прежнему соответствует всему имени файла)
Пример вывода:
foo_factory.py foo_service.pybar_factory.py bar_service.py
3) мы используем xargs с -n 2 для одновременного использования вывода sed 2 строк с разделителями, передавая эти в mv (я также добавил туда параметр -p, чтобы вы могли чувствовать себя в безопасности при запуске этого). вуаля.
Вы можете попробовать следующее:
для файла в * .jpg; сделать mv $ file $ somestring _ $ {file: ((- 7))} done
Вы можете увидеть «расширение параметров» в man bash
, чтобы лучше понять вышесказанное..
Вы можете попробовать это:
для файла в * .jpg; сделать mv $ file $ somestring _ $ {file: ((- 7))} done
Вы можете увидеть «расширение параметра» в man bash
, чтобы понять тем лучше.
Не могу прокомментируйте ответ Сусама Пала, но если вы имеете дело с пробелами, я бы заключил их в кавычки:
для f в * .jpg; do mv "$ f" "` echo $ f | sed s// -/g` "; готово;
Не могу комментировать ответ Сусама Пала, но если вы имеете дело с пробелами, я бы заключил их в кавычки:
для f в * .jpg; do mv "$ f" "` echo $ f | sed s// -/g` "; готово;