Пакетне перейменування файлів


149

У мене каталог із зображеннями:

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

І я хотів би одноразовий перейменувати їх на (сказати).

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

Як це зробити?


8
Це одне з найпоширеніших поширених запитань про командний рядок Unix, і я вже не можу його знайти на цьому веб-сайті, тому ми повинні зробити цю спільноту Wiki?
Жиль

5
Я не бачу, чому. Це специфічне запитання з відповіді, яку можна перевірити.
Інтернет-людина

3
Якщо ви працюєте з X, це не набагато простіше, ніж thunar -B *.pngдля інструменту для перейменування гуй-перейменування Thunar.
dotjoe

@dotjoe Спасибі, Thunar дійсно цікаво.
Волкер Зігель

Відповіді:


105

Якщо ви використовуєте Bash або іншу сумісну з POSIX оболонку:

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

2
Це один із методів заміни параметрів, показаний у Mendel Coopers Advanced Bash-scripting guide tldp.org/LDP/abs/html
W_Whalley

2
@W_Whalley Я настійно рекомендую уникати цього посібника на користь Посібника Wooledge Bash .
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, ви можете використовувати команду rename. Це sed для імен файлів.
ctrl-alt-delor

41

змв

Оболонка zsh має потужну команду пакетного перейменування zmv.

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

autoload zmv

Основний синтаксис - це zmv PATTERN REPLACEMENT. Візерунок являє собою вираження глобальної оболонки. Частини візерунка можуть бути оточені дужками. Текст заміни може містити $1і $2т. Д. Для посилання на N-ту круглу групу в шаблоні. Наприклад:

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

Ви також можете попросити zsh автоматично визначити $1, $2і т.д., щоб відповідати символам підстановки у шаблоні:

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

4
sweeeeeeeeeeeeeeeeeet. ще одна причина, що я повинен вчитися ЗШ.
ixtmixilix

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

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

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

33

Я зазвичай використовую приємну та просту утиліту mmv ( man page ) для цієї справи:

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

виконає ваше завдання.

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

Не забудьте захистити візерунки від оболонки, цитуючи.


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

Дякую, я додав ще трохи інформації у відповідь, щоб було зрозуміліше.
Марсель Стімберг

3
Не можете підняти це достатньо! Це так просто і привітно. Доступно для OS X на домашній мові.
Грег Дубіцький

9

POSIX sh для циклу

Використовує 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

Команда qmvз 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

рекурсивний

легкий рекурсивний вибір файлів image * 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 є безліч варіантів перейменування пакетних файлів, але я не бачив жодних коротких коментарів у назві бренда, які вискочили б у мене.

Особливості:

  • Крос-платформа . Підтримка Windows, Mac OS X та Linux.
  • Безпечний . При перевірці потенційних конфліктів і помилок .
  • Фільтрація файлів . Підтримка включення та виключення файлів за допомогою регулярного вираження. Не потрібно запускати такі команди, як 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не є ні необхідним, ні гарною ідеєю .
якийro
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.