Массовое переименование файлов
У меня есть несколько файлов:
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,
8 ответов
Устанавливать renameutils и использовать qmv с вашим любимым текстовым редактором.
qmv загружает все имена в ваш редактор, а когда вы сохраняете и закрываете его, он применяет ваши изменения к реальным файлам. Если изменения противоречивы (например, два файла имеют одно и то же имя), они будут прерваны, ничего не трогая. Он также правильно обрабатывает циклические переименования.
Я обычно делаю:
$ qmv -f do
так что он показывает только один столбец имен (do: destination-only). Вот как это выглядит:

Если вы объедините его с несколькими курсорами SublimeText, Atom или Visual Studio Code, это станет очень хорошим и мощным инструментом для массового переименования. Например, для Atom, вы бы сделали EDITOR="atom -w" qmv -f do,
Использование 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обратные ссылки на вещи, сопоставленные ранее и сохраненные с()
Обратите внимание * в конце команды сопоставляются все видимые файлы в текущем каталоге. При необходимости используйте более подходящий шарик.
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'
Другая 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,
Вы также можете использовать следующее. Сначала сделайте резервную копию ваших файлов и попробуйте это:
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 .
Вы, вероятно, закончили, но вот (все просто) bash решение:
Является ли "простой... решение проблемы 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: логика в цикле была проверена с одним из ваших примеров имен файлов. Это прошло.
Если бы вы могли использовать графический интерфейс, я бы порекомендовал pyRenamer.
Он присутствует в большинстве дистрибутивов, например, в Ubuntu:
sudo apt-get install pyrenamer
Он может делать все, что вы хотите и даже больше.
- Он может использовать шаблоны, добавлять или подавлять текст.
- Он может получить доступ к данным EXIF при переименовании фотографий, поэтому вы можете создавать шаблоны на основе даты / времени и т. Д.
- Может использовать некоторые метаданные при переименовании музыкальных файлов.
- Кроме того, он имеет предварительный просмотр, который может предотвратить некоторые ошибки, которые трудно исправить.
Вот ваш сырой встроенный find + xargs + sed + mv Oneliner (любовь, любовь):
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при маркировке имен файлов, чтобы избежать проблем с пробелами в середине (но не в вашем случае)mv "$filename" $(echo "${filename}" | sed "s/\([0-9]\{8\}\)_\([0-9]\{6\}\)_\([0-9]\{4\}\)/\1\2\3_TIMING/g");: (обратная косая черта вsedРегулярные выражения не помогают его удобочитаемости, но это просто) переименуйте каждый файл, заменив разделенную подчеркиванием последовательность из 8+6+4 цифр их смежной конкатенацией плюс это_TIMINGвещь (\iэто обратная ссылка наiгруппа регулярных выражений).
Refs: Xargs - человек сед