Переименование сотен файлов одновременно для правильной сортировки

23

У меня есть тонны файлов, все названные вещи , как 1.jpg, 2.jpg, 3.jpgи так далее до 1439.jpg, однако, у меня есть проблема с одним из моих проектов и в алфавитном порядке. Это, как правило , идут в том порядке 1.jpg, 10.jpg, 11.jpgи так далее.

Мне нужен какой-то способ присвоения имен файлам, чтобы они были в таком формате, как 00001.jpgвсе до 01439.jpg.

Как я смогу сделать это быстро и эффективно?

Каз Вулф
источник
То, что вы ищете, это «естественная сортировка», может быть, это поможет: askubuntu.com/questions/41390/…
Фабиан Блехшмидт
Ответ, который не является прямым ответом? ls -v unix.stackexchange.com/questions/33909/…
WernerCD
+1, потому что я безуспешно пытался сделать это в pyrenamer.
Парто
@FabianBlechschmidt, мне нужно это в программе, которая не предназначена для nautilus или подобного. Это для индивидуального проекта.
Каз Вулф
Я думаю, вы думали о реализации естественной сортировки? Но я понимаю, что переименование файлов довольно легко, и если оно делает свою работу, прекрасно :)
Фабиан Блехшмидт

Ответы:

35

Ubuntu поставляется со скриптом под названием rename. Это всего лишь небольшой Perl-скрипт, который имеет ряд мощных функций массового переименования, но лучшей (в данном случае) является возможность запуска Perl во время замены. Результатом является действительно компактное решение:

rename 's/\d+/sprintf("%05d", $&)/e' *.jpg

Это похоже на printfответы в другом стиле, но это все для нас. Код выше для 5-значного числа (включая переменное число ведущих нулей).

Он будет искать и заменять первую найденную числовую строку на версию с нулевым дополнением и оставит остальную часть имени файла в покое. Это означает, что вам не нужно слишком беспокоиться о переносе какого-либо расширения или префикса.

Примечание: это не полностью переносимо. Многие дистрибутивы используют rename.ulиз util-linuxпакета в качестве renameбинарного файла по умолчанию . Это значительно замедленная альтернатива (см. man rename.ul), Которая не поймет вышеизложенного. Если вам это нужно на платформе, которая не использует переименование Perl, сначала узнайте, как ее установить.


А вот и тестовая подвеска:

$ touch {1..19}.jpg

$ ls
10.jpg  12.jpg  14.jpg  16.jpg  18.jpg  1.jpg  3.jpg  5.jpg  7.jpg  9.jpg
11.jpg  13.jpg  15.jpg  17.jpg  19.jpg  2.jpg  4.jpg  6.jpg  8.jpg

$ rename 's/\d+/sprintf("%05d", $&)/e' *.jpg

$ ls
00001.jpg  00005.jpg  00009.jpg  00013.jpg  00017.jpg
00002.jpg  00006.jpg  00010.jpg  00014.jpg  00018.jpg
00003.jpg  00007.jpg  00011.jpg  00015.jpg  00019.jpg
00004.jpg  00008.jpg  00012.jpg  00016.jpg

И пример префиксов (мы не делаем ничего другого):

$ touch track_{9..11}.mp3 && ls
track_10.mp3  track_11.mp3  track_9.mp3

$ rename 's/\d+/sprintf("%02d", $&)/e' *.mp3 && ls
track_09.mp3  track_10.mp3  track_11.mp3
Оли
источник
Если бы я был Perl-человеком, это было бы идеальным решением. Действительно аккуратно.
MGP
2
Он не использует никакого Perl, только предоставленный инструмент, который уже написан на Perl.
Роб
1
В этом случае он делает включать одну команду Perl , но это не совсем тяжелая атлетика. sprintfв Perl ведет себя аналогично sprintfдругим языкам.
Оли
21
for f in *.jpg ; do if [[ $f =~ [0-9]+\. ]] ; then  mv $f `printf "%.5d" "${f%.*}"`.jpg  ; fi ; done

редактировать

Объяснение:

  • if [[ $f =~ [0-9]+\. ]] следит за тем, чтобы переименовывались только файлы с именами, состоящими из цифр (с точками).
  • printf "%.5d" NUMBER добавляет ведущие нули
  • "${f%.*}" вырезает расширение (.jpg) и оставляет только номер
  • .jpgпосле второго обратного удара снова добавляется расширение файла.

Обратите внимание, что это будет работать только с именами файлов, которые являются числами. Отступ слева от нуля к ненумерованным файлам требует другого формата.

Если вы хотите поэкспериментировать, попробуйте эту команду:

for f in *.jpg ; do if [[ $f =~ [0-9]+\. ]] ; then echo mv $f `printf "%.5d" "${f%.*}"`.jpg  ; fi ; done

Редактировать 2

Сделайте команду более безопасной, убедившись, что только имена файлов, которые являются числами, переименовываются. Обратите внимание, что любые ранее существующие файлы с именами, такими как 00001.jpg, будут перезаписаны.

sмurf
источник
Этот скрипт работает «из коробки» на Ubuntu и других дистрибутивах Linux! 😃 Не нужно устанавливать никаких дополнительных инструментов, используя perl, python и т. Д.
HEXcube
6

Ниже скрипт на питоне.

Скрипт добавляет начальные нули до определенного количества цифр. Если имя больше этого, файл (имя) остается без изменений.

Объединение различных расширений в одно действие переименования может добавить некоторое удобство. Чтобы добавить расширения, просто добавьте их, например, в кортеж extensions = (".jpg", ".jpeg", ".tiff").

Скопируйте текст в пустой файл, сохраните его как rename.py, введите правильный путь к каталогу файлов ( sourcedir), количество цифр, которые вы хотели бы иметь новыми именами ( number_ofdigits), и расширение (я) файлов для rename ( extensions)

Запустите его командой:

python3 /path/to/script/rename.py

Сценарий:

#!/usr/bin/python3

import shutil
import os

sourcedir = "/path/to/files"; number_ofdigits = 5; extensions = (".jpg", ".jpeg")

files = os.listdir(sourcedir)
for item in files:
    if item.endswith(extensions):
        name = item.split("."); zeros = number_ofdigits-len(name[0])
        newname = str(zeros*"0")+name[0]+"."+name[1]
        shutil.move(sourcedir+"/"+item, sourcedir+"/"+newname)

редактировать:

Ниже немного улучшенная версия. Он автоматически определяет самое длинное имя в каталоге и добавляет начальные нули вплоть до длины самого длинного имени.

пример:

1.jpg
12.jpg
123.jpg

будет выглядеть так:

001.jpg
012.jpg
123.jpg

Нет необходимости устанавливать количество цифр.

#!/usr/bin/python3

import shutil
import os

sourcedir = "/path/to/files"; extensions = (".jpg", ".jpeg")
files = [(f, f[f.rfind("."):], f[:f.rfind(".")]) for f in os.listdir(sourcedir)if f.endswith(extensions)]
maxlen = len(max([f[2] for f in files], key = len))

for item in files:
    zeros = maxlen-len(item[2])
    shutil.move(sourcedir+"/"+item[0], sourcedir+"/"+str(zeros*"0")+item[0])
Якоб Влейм
источник
2

В Perl реализована утилита переименования, которая делает это очень просто:

rename 's/\d+/sprintf("%05d",$&)/e' *.jpg

Первый аргумент - это выражение Perl, которое оценивается для каждого имени файла.

Матс Киндал
источник
0

Существует графический интерфейс, который будет делать это, называемый pyRenamer, который можно найти в репозиториях. Установите, запустите, выберите каталог и просто установите для параметра «Переименованный шаблон имени файла» значение «{num5}» на вкладке «Шаблоны» и нажмите кнопку «Переименовать». Вы также можете просмотреть, что произойдет до переименования.

user287888
источник
Пока ваш ответ работает, обратите внимание, что это shell-scriptingраздел, то есть я ищу ответ из командной строки. Кроме того, можете ли вы предоставить более подробную информацию о программе? Например, какой формат шаблона {num5}?
Каз Вулф
-4
for file in `(find * -maxdepth 1 -type f -name "*.jpg")`     
do    
  mv $file "000"$file    
done

Это грубо, так как он не делает переименование разумно, нужно подумать об этом для хитрости. Но это должно помочь вам разобраться.

Обновление: Ну, у вас есть более полный ответ.

Сварненду Бисвас
источник
2
переименовывается в 1439.jpg в 0001439.jpg.
Авинаш Радж
Да, я знаю, только добавили дополнительные нули, которые все еще должны работать с сортировкой.
Swarnendu Biswas