Масове перейменування файлів


25

У мене є декілька файлів:

10.3.100.179_01_20161018_230014_5335.jpg
10.3.100.179_01_20161018_231514_0814.jpg
10.3.100.179_01_20161018_233014_5706.jpg
10.3.100.179_01_20161018_234514_0896.jpg
10.3.100.179_01_20161018_230114_5395.jpg
10.3.100.179_01_20161018_231614_1145.jpg
10.3.100.179_01_20161018_233114_6047.jpg
10.3.100.179_01_20161018_234614_0547.jpg
10.3.100.179_01_20161018_230114_5492.jpg
10.3.100.179_01_20161018_231614_1264.jpg
10.3.100.179_01_20161018_233114_6146.jpg
10.3.100.179_01_20161018_234614_0658.jpg
10.3.100.179_01_20161018_230214_5630.jpg
10.3.100.179_01_20161018_231714_7135.jpg

Я хочу перейменувати цей формат:

10.4.100.135_01_20161013131108389_TIMING.jpg
10.4.100.135_01_20161013131111390_TIMING.jpg
10.4.100.135_01_20161013131114401_TIMING.jpg
10.4.100.135_01_20161013131117431_TIMING.jpg
10.4.100.135_01_20161013131120418_TIMING.jpg
10.4.100.135_01_20161013131123461_TIMING.jpg
10.4.100.135_01_20161013131126511_TIMING.jpg

Потрібно зняти _часову позначку та додати _TIMING.



5
Будь ласка, використовуйте послідовні приклади у своїх питаннях. Схоже, ви хочете замінити 10.3.100.179їх 10.4.100.135. Це те, що ви хочете, або ви просто хочете видалити _TIMINGта _з часу?
тердон

3
Добрий час, щоб нагадати людям, що існує стандарт iso8601 для дат (які працюють як для імен файлів, так і для записів журналу) ^^ Тож, можливо, вам слід переглянути перейменування на: YYYY-MM-DDThh: mm: ss.mmm (ex : ваш перший файл став би: 10.4.100.135_01_2016-10-13T13:11:08.389_TIMING.jpg(і "TIMING" потім можна було навіть видалити, оскільки він зараз схоже на дату та годину (і мілісекунди), особливо коли стандарт стає більш поширеним. T є частиною стандарту, і я виріс так, як це подобається (і витягування його порушує стандарт ^ ^)
Олів'є Дулак

@OlivierDulac Я б не рекомендував використовувати :ім'я файлу. Я вважаю, що Windows не підтримує це.
Джастін

@ Джустін хороший момент. стандарт рекомендує скинути його для імен файлів. Я надав
вкладену

Відповіді:


38

Встановіть renameutilsі використовуйте qmvулюблений текстовий редактор.

qmvзавантажує всі імена у ваш редактор, і коли ви зберігаєте та закриваєте, він застосовує ваші зміни до фактичних файлів. Якщо зміни будуть суперечливими (наприклад, два файли отримують однакове ім’я), вони перестануть працювати, нічого не торкаючись. Він також правильно обробляє кругові перейменування.

Я зазвичай роблю:

$ qmv -f do

щоб він відображав лише один стовпець імен (do: лише призначення). Ось як це виглядає:

qmw

Якщо поєднувати його з декількома курсорами SublimeText, Atom або Visual Studio Code, це дуже гарний та потужний інструмент для масового перейменування. Наприклад, для Atom, ви б це зробили EDITOR="atom -w" qmv -f do.


1
Ласкаво просимо запитатиUbuntu! Це так круто!
αғsnιη

Підписали це просто на +! це. ;)
Дж. Аллан

2
Нічого собі, приємний інструмент і приємна анімація GIF. Чудова перша відповідь, будь ласка! :)
Байт командир

1
Дякуємо @KasiyA за вбудоване зображення і дякую всім за позитивні коментарі.
ateijelo

1
@kasperd Так, він попередить, що план перейменування містить помилки та відкриє інтерактивну консоль, де можна вжити подальших дій.
ateijelo

27

Використовувати rename...

rename -n 's/^([0-9]+\.[0-9]\.[0-9]+\.[0-9]+_[0-9]+_)([0-9]+)_([0-9]+)_([0-9]+)\.jpg/$1$2$3$4_TIMING\.jpg/' *

З -nцим виведете те, що будете робити, не вносячи жодних змін:

rename(10.3.100.179_01_20161018_230014_5335.jpg, 10.3.100.179_01_201610182300145335_TIMING.jpg)
rename(10.3.100.179_01_20161018_231514_0814.jpg, 10.3.100.179_01_201610182315140814_TIMING.jpg)
rename(10.3.100.179_01_20161018_233014_5706.jpg, 10.3.100.179_01_201610182330145706_TIMING.jpg)
rename(10.3.100.179_01_20161018_234514_0896.jpg, 10.3.100.179_01_201610182345140896_TIMING.jpg)

Якщо це виглядає правильно, видаліть -n

$ rename 's/^([0-9]+\.[0-9]\.[0-9]+\.[0-9]+_[0-9]+_)([0-9]+)_([0-9]+)_([0-9]+)\.jpg/$1$2$3$4_TIMING\.jpg/' *
$ ls
10.3.100.179_01_201610182300145335_TIMING.jpg  10.3.100.179_01_201610182330145706_TIMING.jpg
10.3.100.179_01_201610182315140814_TIMING.jpg  10.3.100.179_01_201610182345140896_TIMING.jpg

Пояснення ...

  • s/something/something_else/ пошук і заміна
  • ^ початок назви (прив’язка)
  • [0-9] будь-яке число
  • + один або кілька попередніх символів
  • \.буквальний .(без \цього не відповідає жоден символ)
  • () щоб зберегти цю частину
  • $1$2$3$3 Зворотні посилання на речі, які збігалися раніше та зберігалися ()

Примітка: *в кінці команди відбувається узгодження всіх видимих ​​файлів у поточному каталозі. При необхідності використовуйте більш підходящий глобус.


2
У деяких дистрибутивах ця команда доступна як prename(p для perl, оскільки перший аргумент - це вираз perl)
Пітер Кордес

12

mmv можна зробити так, як у наступному:

mmv '*_*_*_*_*.jpg' '#1_#2_#3#4#5_TIMING.jpg'

10.3.100.179_01_20161018_230014_5335.jpg 10.3.100.179_01_201610182300145335_TIMING.jpg

# 1, # 2, # 3, ... посилає кожного на відповідне "*" тут.

Він ще коротший із:

mmv '*_*_*.jpg' '#1#2#3_TIMING.jpg'

9

Інший renameпідхід:

$ rename -n 's/(.*)_(.*)_(.*)\./$1$2$3_TIMING./' *
10.3.100.179_01_20161018_230014_5335.jpg -> 10.3.100.179_01_201610182300145335_TIMING.jpg
10.3.100.179_01_20161018_230114_5395.jpg -> 10.3.100.179_01_201610182301145395_TIMING.jpg
10.3.100.179_01_20161018_230114_5492.jpg -> 10.3.100.179_01_201610182301145492_TIMING.jpg
10.3.100.179_01_20161018_230214_5630.jpg -> 10.3.100.179_01_201610182302145630_TIMING.jpg
10.3.100.179_01_20161018_231514_0814.jpg -> 10.3.100.179_01_201610182315140814_TIMING.jpg
10.3.100.179_01_20161018_231614_1145.jpg -> 10.3.100.179_01_201610182316141145_TIMING.jpg
10.3.100.179_01_20161018_231614_1264.jpg -> 10.3.100.179_01_201610182316141264_TIMING.jpg
10.3.100.179_01_20161018_231714_7135.jpg -> 10.3.100.179_01_201610182317147135_TIMING.jpg
10.3.100.179_01_20161018_233014_5706.jpg -> 10.3.100.179_01_201610182330145706_TIMING.jpg
10.3.100.179_01_20161018_233114_6047.jpg -> 10.3.100.179_01_201610182331146047_TIMING.jpg
10.3.100.179_01_20161018_233114_6146.jpg -> 10.3.100.179_01_201610182331146146_TIMING.jpg
10.3.100.179_01_20161018_234514_0896.jpg -> 10.3.100.179_01_201610182345140896_TIMING.jpg
10.3.100.179_01_20161018_234614_0547.jpg -> 10.3.100.179_01_201610182346140547_TIMING.jpg
10.3.100.179_01_20161018_234614_0658.jpg -> 10.3.100.179_01_201610182346140658_TIMING.jpg

Якщо це, здається, працює так, як ви цього хочете, видаліть -n.


5

Ви також можете скористатися наступним. Спочатку візьміть резервну копію своїх файлів і спробуйте це:

find . -name "*.jpg" -type f -print0| while read -d $'\0' file
do
    #extension="${file##*.}"
    newfilename=$(echo "${file%.*}" | sed 's/\(.*\)_\(.*\)_/\1\2/')
    mv "$file" "$newfilename""_TIMING.jpg"
done

sed 's/\(.*\)_\(.*\)_/\1\2/')видаляє _символи в часовій позначці.

Наприклад:

user@host$ ls -lart
total 8
drwxrwxr-x 6 user user 4096 Oct 21 10:21 ..
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230014_5335.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231514_0814.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_233014_5706.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_234514_0896.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230114_5395.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231614_1145.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_233114_6047.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_234614_0547.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230114_5492.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231614_1264.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_233114_6146.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_234614_0658.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230214_5630.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231714_7135.jpg
drwxrwxr-x 2 user user 4096 Oct 21 10:30 .

user@host$ find . -name "*.jpg" -type f -print0 | while read -d $'\0' file
> do
>  newfilename=$(echo "${file%.*}" | sed 's/\(.*\)_\(.*\)_/\1\2/')
>  mv $file $newfilename"_TIMING.jpg"
> done

10:35:20 t $ ls -lart
total 8
drwxrwxr-x 6 user user 4096 Oct 21 10:21 ..
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182300145335_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182315140814_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182330145706_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182345140896_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182301145395_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182316141145_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182331146047_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182346140547_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182301145492_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182316141264_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182331146146_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182346140658_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182302145630_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182317147135_TIMING.jpg
drwxrwxr-x 2 user user 4096 Oct 21 10:35 .

1
це найкраще рішення. Звичайно, думка Zanna ідеально підходить для декількох файлів, але оскільки глобалізація виконується оболонкою, їх рішення може не працювати на великій кількості файлів (командний рядок занадто довгий).
rexkogitans

@rexkogitans: Якщо ви працюєте в сучасній системі Linux (тобто будь-якій версії Ubuntu), обмеження довжини командного рядка становить кілька мегабайт. І якщо це проблема, ви можете використовувати find -maxdepth 1 -exec rename ... {} +пакетне перелічення поточного каталогу в командному рядку перейменувати. (додайте -name *.jpgабо що завгодно). Це виконає набагато швидше, ніж цикл оболонки, який forks + execs sedі mvдля кожного імені файлу, а не просто системний виклик перейменувати. (Ви могли позбутися sedвикористання вбудованих регекс-файлів bash, але розгалуження mvвсе ще відбувається повільно.)
Пітер Кордес

2

Ви, мабуть, закінчили, але ось (просте) все bashрішення:
чи "простий ... баш-розчин" є оксимороном?

#!/bin/bash

#loop through all files ending in .jpg
for f in *.jpg;
do

    #cut out everything to the timestamp
    firsthalf=${f%_*_*_*}

    #get from the timestamp on
    lasthalf=${f#*_*_}

    #remove (all) underscores from timestamp
    #note the 2 forward slashes...
    lasthalf=${lasthalf//_/}

    #get our extension
    ext=${lasthalf##*.}

    #now we can remove the extension
    lasthalf=${lasthalf%.*}

    #rename the file
    #change `mv` to `echo` if you want to do a trial run first...
    mv "$f" "${firsthalf}_${lasthalf}_TIMING.${ext}"

done;

PS: Логіка в циклі була протестована однією з ваших прикладних імен файлів. Це минуло.


1
Напевно, краще скористатися багге-реджексом з [[ $f ~= (.*)_(.*)_(.*)_(.*)\.jpg ]]; newname=${BASH_REMATCH[1]${BASH_REMATCH:2:4}TIMING.jpgчимось іншим . (абсолютно неперевірений і, мабуть, неправильний, але загальна ідея полягає в тому, що групи захоплення переходять у масив BASH_REMATCH.)
Пітер Кордес

@PeterCordes: Це хороший момент! Я ніколи не використовував ( bash) захоплення груп, і якщо бути чесним, баш - це не перша мова, з якою я б їх спробував. (Я думаю bash, це некрасива мова.) Все-таки це гарне рішення, і воно навчило мене чогось такого кудо.
Дж. Аллан

Так, головна причина такої великої обробки тексту в чистому стилі - це написання функцій заповнення вкладок, які повинні бути швидкими. Це додає абсолютно нового значення фразі "потворний код" ...
Пітер Кордес

@PeterCordes: Я розумію, що я не вважаю, що код "некрасивий". Це може бути не 2-х рядкове рішення, яке ви дали, але читати, наскільки я не важко, це не важко; плюс це добре прокоментується ...
Дж. Аллан

Я говорив про те, що загальнозміцнюючий код взагалі некрасивий (або принаймні важко читати). Це насправді не дуже потворно, лише дещо згинає розум (наприклад, передача аргументів за допомогою ref в bash, що здійснюється шляхом передачі імені змінної та використання виклику printf -v "$3" ...для встановлення змінної, ім'я якої входить $3.) Розділення всього командного рядка та повернення його назад разом досить важко слідкувати / налагоджувати, принаймні я знайшов це таким чином, намагаючись очистити / виправити помилки. Дивіться код на github
Пітер Кордес

1

Якщо ви можете використовувати GUI, я рекомендую pyRenamer .

Він присутній у більшості дистрибутивів, наприклад, в Ubuntu:

sudo apt-get install pyrenamer

Він може робити все, що завгодно, і більше.

  • Він може використовувати шаблони, додавати або придушувати текст.
  • Він може отримати доступ до даних EXIF ​​при перейменуванні фотографій, тож ви можете генерувати шаблони на основі дати / часу тощо.
  • Можна використовувати деякі метадані при перейменуванні музичних файлів.
  • Більше того, у нього є попередній перегляд , який може запобігти деякі помилки, які важко відновити.

Спонсору ... Потрібно пояснити, чому? ОП не вказав, чи був GUI варіант чи ні. Я бачу, що більшість відповідей йде на консоль / скрипт, але багато користувачів оцінять рішення GUI. А може, pyRenamer має якийсь недолік, про який я не знаю. У будь-якому випадку, мені подобається знати причини попутних вод.
jrierab

Можливо, я також пропоную Thunar Bulk Renamer для швидкого інтерактивного підходу GUI.
Тоні Мартін

@TonyMartin Це слід зауважити, це не має нічого спільного з відповіддю
Сергій Колодяжний

0

Ось ваш вбудований find + xargs+ sed+ mvoneliner (love oneliners):

find . -name "*.jpg" -print0 | sort -z | xargs -0 sh -c 'for filename; do mv "$filename" $(echo "${filename}" | sed "s/\([0-9]\{8\}\)_\([0-9]\{6\}\)_\([0-9]\{4\}\)/\1\2\3_TIMING/g"); done' sh

Пояснення:

  • find . -name "*.jpg" | sort | xargs sh -c <command> sh : перерахуйте всі JPEG у поточному каталозі, потім виконайте команду оболонки для кожного (звичайно, сортування необов’язково, але зберігайте речі дещо чистішими, якщо ви кудись входите)

  • -print0, -z, -0: Це хороша звичка до окремих пунктів з двійковим 0коли tokenizing імен файлів , щоб уникнути проблем з в-середини білого-простір (не ваш випадок , хоча)

  • mv "$filename" $(echo "${filename}" | sed "s/\([0-9]\{8\}\)_\([0-9]\{6\}\)_\([0-9]\{4\}\)/\1\2\3_TIMING/g");: (Слеш sed«s регулярного вираження не допоможе читання, але це просто) перейменувати кожен файл, замінивши підкреслення-separeted послідовності 8 + 6 + 4 цифр з їх безперервної конкатенацией плюс цієї _TIMINGріччю ( \iв зворотну посилання на i- ть регекс-група).


Відгуки : Xargs - людина sed

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.