Переименуйте несколько файлов, заменив определенный шаблон в именах файлов с помощью сценария оболочки [дубликат]

Напишите простой скрипт, который автоматически переименовывает несколько файлов. В качестве примера мы хотим, чтобы файл * 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" обозначение. Вам нужны двойные кавычки, чтобы сохранить пробелы.


181

Вы можете использовать утилиту rename для переименования нескольких файлов по шаблону. Например, следующая команда добавит строку MyVacation2011_ ко всем файлам с расширением jpg.

  переименовать 's/^/MyVacation2011_/g' * .jpg  

или

   переименовать    

Поделиться
Улучшить этот ответ
отредактировано 1 июня ’16 в 17:10
KaiserKatze
1,16811 золотых знаков1515 серебряных знаков2929 бронзовых знаков
ответил 29 июля ’13 в 12:05
  • Но должны быть варианты эти команды, переименование аналогично 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 ​​
| показать 3 дополнительных комментария

Вы можете использовать утилиту rename для переименовать несколько файлов по шаблону. Например, следующая команда добавит строку MyVacation2011_ ко всем файлам с расширением jpg.

  переименовать 's/^/MyVacation2011_/g' * .jpg  

или

   переименовать    

38

  для файла в формате * .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
и так далее …

Поделиться
Улучшить этот ответ
ответил 22 июля ’13 в 9:45
  • 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
и т. д.


36

В этом примере я предполагаю, что все ваши файлы изображений начинаются с «IMG», и вы хотите заменить «IMG» на «VACATION»

решение: сначала идентифицировали все файлы jpg, а затем заменили ключевое слово

  find.  -name '* jpg' -exec bash -c 'echo mv $ 0 $ {0/IMG/VACATION}' {} ;   

Поделиться
Улучшите этот ответ
ответ дан 07 июля ’17 в 07:59
  • 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}' {} ;   

4

Другой вариант — :

  для i in * 001.jpgdo echo "mv $ i yourstring $ {i # * 001.jpg}" done  

удалить echo после того, как все будет правильно.

Замена параметра на # сохранит только последнюю часть, поэтому вы может изменить свое имя.

Поделиться
Улучшите этот ответ
отредактировано 5 мая ’16 в 14:12
ответил 4 мая ’16 в 19:57
добавить комментарий |

Другой вариант:

  для i in * 001.jpgdo echo "mv  $ i yourstring $ {i # * 001.jpg} "готово  

удалить echo , когда все будет правильно.

При замене параметра на # останется только последняя часть, поэтому вы можете изменить ее имя.


2
  найти.  -тип 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, чтобы вы могли чувствовать себя в безопасности при запуске этого).

Поделиться
Улучшите это ответ
изменён 15 окт. в 16:42
ответил 13 октября ’16 в 19:24
добавить комментарий |

  найти.  -тип 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, чтобы вы могли чувствовать себя в безопасности при запуске этого). вуаля.


1

Вы можете попробовать следующее:

  для файла в * .jpg; сделать mv $ file $ somestring _ $ {file: ((- 7))} done  

Вы можете увидеть «расширение параметров» в man bash , чтобы лучше понять вышесказанное..

Поделиться
Улучшите это ответ
ответ дан 23 июл ’11 в 20:03
добавить комментарий |

Вы можете попробовать это:

  для файла в * .jpg; сделать mv  $ file $ somestring _ $ {file: ((- 7))} done  

Вы можете увидеть «расширение параметра» в man bash , чтобы понять тем лучше.


1

Не могу прокомментируйте ответ Сусама Пала, но если вы имеете дело с пробелами, я бы заключил их в кавычки:

  для f в * .jpg;  do mv "$ f" "` echo $ f | sed s// -/g` ";  готово;  

Поделиться
Улучшите этот ответ
ответил 22 марта ’13 в 20:28
добавить комментарий |

Не могу комментировать ответ Сусама Пала, но если вы имеете дело с пробелами, я бы заключил их в кавычки:

  для f в * .jpg;  do mv "$ f" "` echo $ f | sed s// -/g` ";  готово;  

Оцените статью
Botgadget.ru
Добавить комментарий