Пакетное переименование файлов


151

У меня есть каталог, полный изображений:

image0001.png
image0002.png
image0003.png
...

И я бы хотел, чтобы их переименовали (скажем).

0001.png
0002.png
0003.png
...

Как мне это сделать?


8
Это один из наиболее часто задаваемых вопросов по командной строке Unix, и я не могу найти его на этом сайте, так что мы должны сделать эту вики-страницу сообщества?
Жиль

5
Я не понимаю почему. Это конкретный вопрос с проверяемым ответом.
Интернет человек

3
Если вы работаете с X, это не намного легче, чем thunar -B *.pngс помощью графического инструмента Thunar для массового переименования.
dotjoe

@dotjoe Спасибо, Тунар действительно интересный.
Фолькер Сигел

Ответы:


107

Если вы используете Bash или другую POSIX-совместимую оболочку:

for f in *.png; do
    mv -- "$f" "${f#image}"
done

2
Это один из методов подстановки параметров, показанный в Руководстве по расширенному
W_Whalley

2
@W_Whalley Я настоятельно рекомендую избегать этого руководства в пользу Wooledge Bash Guide .
Wildcard

@Wildcard: каковы ваши причины рекомендовать избегать руководства ABS?
Кристиан Северин

@ChristianSeverin продвижение плохих практик и откровенно испорченного кода. Проверьте ссылки на странице моего профиля.
Wildcard

Если вы не знаете, как адаптировать этот пример для разных шаблонов файлов, вам может понадобиться взглянуть на раздел расширения параметров в руководстве, упомянутом выше.
lex82

108

В Debian и его производных Perl renameработает sedпримерно так:

  rename -v 's/image//' *.png

Там также renameот , util-linuxкоторый работает , как это, вместо того, чтобы :

  rename image '' *.png

6
Вы действительно должны объяснить, что это программа на Perl, которую, возможно, придется установить, и что она принимает регулярные выражения в качестве аргумента.

Ах, я не знал об этом. Я отдам должное каноническому ответу, когда я его идентифицирую :)
Интернет-мужчина

5
Эта renameпрограмма пришла из дистрибутива примеров Perl. Debian и Ubuntu поставляют как /usr/bin/rename. Другие варианты Unix могут не предоставлять его или могут предоставлять совершенно иное /usr/bin/rename.
Жиль

1
Некоторые версии renameзанять от до замены шаблона:rename [options] <expression> <replacement> <file>...
сплавляет

1
Если вы используете систему на основе Debian, тогда sudo apt-get install rename, тогда вы можете использовать команду переименования. Это sed для имен файлов.
Ctrl-Alt-Delor

41

ZMV

В оболочке zsh имеется мощная команда пакетного переименования zmv.

Сначала вам нужно включить zmvкоманду следующим образом (это может войти в вашу ~/.zshrc).

autoload zmv

Основной синтаксис есть zmv PATTERN REPLACEMENT. Шаблон представляет собой выражение оболочки Части шаблона могут быть заключены в круглые скобки. Текст замены может содержать $1, $2и т.д. , чтобы обратиться к группе N - й скобках , в шаблоне. Например:

zmv 'image(*.png)' '$1'

Вы также можете попросить ЗШ автоматически определять $1, $2и т.д. , чтобы соответствовать подстановочные символы в шаблоне:

zmv -w 'image*.png' '$1.png'

4
sweeeeeeeeeeeeeeeeeet. Еще одна причина, по которой я должен изучать Zsh.
ixtmixilix

1
@ixtmixilix что учить? Просто начните использовать его и, возможно, добавьте prezto ( github.com/sorin-ionescu/prezto ) для некоторой дополнительной привлекательности.
Джерри

Действительно круто, как указано в man zmv, это можно еще больше упростить, добавив псевдоним mmv = 'noglob zmv -W' к: mmv * .c.orig orig / *. C
Брецко,

Включение zmvпрезто требует раскомментирования строки в вашем ~ / .zpreztorc после # Set the Zsh functions to load (man zshcontrib).предоставленияzstyle ':prezto:load' zfunction 'zargs' 'zmv'

33

Обычно я использую удобную и простую утилиту mmv ( man-страницу ) для этого сценария:

$ mmv "image*.png" "#1.png"

выполню вашу задачу.

#1В целевом шаблоне будет заменена независимо соответствует групповой символ в шаблоне источника. Это также работает для нескольких подстановочных знаков и может использоваться, например, для изменения порядка частей имен файлов. Вы также можете легко делать более сложные вещи, такие как преобразование строчных букв в прописные.

Обязательно защищайте шаблоны от оболочки, заключая в кавычки.


Спасибо за указание на эту утилиту. Я нашел это в репозиториях Debian, Ubuntu и Cygwin. У меня были проблемы со страницей руководства, но я нашел несколько веб-страниц и этот вопрос о переполнении стека, который помог объяснить, как вы его использовали. stackoverflow.com/questions/417916/how-to-do-a-mass-rename
W_Whalley

Спасибо, я добавил еще немного информации в ответ, чтобы сделать его более понятным.
Марсель Стимберг

3
Не могу высказать это достаточно! Это так просто и дружелюбно. Доступно для OS X на доморощенном.
Грег Дубицки

9

POSIX ш для петли

Использует sed для переименования

for i in image*jpg
do 
  mv -v "$i" "$(echo "$i" | sed -e 's/^\.\/image//' - )"
done

6

Perl мне нравится так:

perl -nlE '$old=$_; s/image//; qx(mv $old $_)'

Вы также можете использовать тот же шаблон для других задач, таких как копирование файлов в другой каталог:

perl -nlE '$old=$_; s(image)(/path/to/new/dir/); qx(mv $old $_)'

2
Или (безопаснее!):rename($old,$_)
reinierpost

5

qmv

Команда qmvfrom renameutilsоткрывает редактор, показывающий список имен файлов с двумя столбцами, разделенными вкладкой. В каждой строке показано одно из имен файлов, одинаковое в обоих столбцах. Правый столбец представляет новые имена файлов.
Чтобы внести изменения, отредактируйте имена справа. В этом примере :%s/...или визуальный режим блока полезны.

Имена файлов в вашем редакторе

$ qmv *.png

В редакторе:

image0001.png           image0001.png
image0002.png           image0002.png
image0003.png           image0003.png         
~                                             
~                                             
~                                             
~                                             
"/tmp/user/1000/qmvxWyVMs" 3L, 93C

Редактировать имена в правом столбце:
(удаление imageпрефикса из всех строк в режиме визуального блока)

image0001.png           0001.png
image0002.png           0002.png
image0003.png           0003.png         
~                                             
~                                             
~                                             
~                                             
:wq

Журнал переименования:

image0001.png -> 0001.png
image0002.png -> 0002.png
image0003.png -> 0003.png

(например , Ubuntu: apt-get install renameutils)


3

рекурсивный

легко рекурсивно выбирает файлы изображений * png и предполагает, что нет необходимости иметь дело с переводом строки в именах файлов

find . -name "image*.png" | while read f; do mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"; done

Безопасный, может работать с пробелами, новыми строками, обратными слешами и всем остальным :

find . -name "image*.png" | while IFS= read -r f; do 
   mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"; 
done

1

POSIX sh используя цикл while

Чтение имен из findкоманды.

find . -maxdepth 1 -type f -name 'image*png' | while IFS= read -r f; do
  mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"
done

Чтение имен из файла

while IFS= read -r f; do mv -v "$f" "$(echo "$f"|sed -e 's/^\.\/image//' - )"; done < flist


1

Для Windows и Linux этот скрипт на Perl подойдет; в этом случае:

$ rnm -l 's/^image//' '*.png'

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

$ rnm -r 's/^/$counter./' '/\.png$/'

Символы UTF-8 также правильно обрабатываются как в Windows, так и в Linux.


0

Вы можете использовать этот инструмент: RNM ( веб-страница )

Для вашего случая команда будет:

rnm -rs '/^image//' *.png

Вы можете найти больше примеров / документов здесь .


0

Попробуйте brename ( https://github.com/shenwei356/brename ), практичный кроссплатформенный инструмент командной строки для безопасного пакетного переименования файлов / каталогов с помощью регулярных выражений (с поддержкой Windows, Linux и OS X).

@patrickDurusau сказал:

В Linux есть множество опций переименования командных файлов, но я не увидел каких-либо недостатков в brename, которые бросились бы в меня.

Функции:

  • Кроссплатформенный . Поддержка Windows, Mac OS X и Linux.
  • Safe . При проверке потенциальных конфликтов и ошибок .
  • Фильтрация файлов . Поддержка включения и исключения файлов с помощью регулярного выражения. Не нужно запускать такие команды, как find ./ -name "*.html" -exec CMD.
  • Переименование субматча с соответствующим значением через файл значения ключа .
  • Переименование по возрастанию целого числа .
  • Рекурсивное переименование файлов и каталогов .
  • Поддержка холостого хода .
  • Красочный вывод .

Команда:

$ brename -f .png -p image
[INFO] checking: [ ok ] 'image0001.png' -> '0001.png'
[INFO] checking: [ ok ] 'image0002.png' -> '0002.png'
[INFO] checking: [ ok ] 'image0003.png' -> '0003.png'
[INFO] 3 path(s) to be renamed
[INFO] renamed: 'image0001.png' -> '0001.png'
[INFO] renamed: 'image0002.png' -> '0002.png'
[INFO] renamed: 'image0003.png' -> '0003.png'
[INFO] 3 path(s) renamed

-5

ls * png | пока читаешь -rf; do f2 = "` echo $ f | sed -e's / image // '`"; mv $ f $ f2; сделанный


Что-то не так: "mv: отсутствует операнд файла назначения после 'image0001.png'"
Интернет-мужчина

3
Есть много проблем с вашим кодом. Парсинг вывода ls- это просто вызов проблем. readдолжно быть read -r. все замены переменных должны быть в двойных кавычках.
Жиль

Вы могли бы написать это более эффективно, как for f in *png; do f2="$(echo "$f" | sed -e 's/image//')"; mv "$f" "$f2"; done. Разбор не lsявляется ни необходимой, ни хорошей идеей .
Кодзиро
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.