Переименование файлов в папке на последовательные номера
Я хочу переименовать файлы в каталоге в последовательные номера. На основании даты создания файлов.
Для примера sadf.jpg
- 0001.jpg
, wrjr3.jpg
- 0002.jpg
и т.д. количество ведущих нулей в зависимости от общего количества файлов (без необходимости дополнительных нулей).
Ответы
Ответ 1
Попробуйте использовать цикл, let
и printf
для заполнения:
a=1
for i in *.jpg; do
new=$(printf "%04d.jpg" "$a") #04 pad to length of 4
mv -i -- "$i" "$new"
let a=a+1
done
с использованием флага -i
предотвращает автоматическую перезапись существующих файлов.
Ответ 2
Салон в одну строчку:
ls -v | cat -n | while read n f; do mv -n "$f" "$n.ext"; done
Вы можете изменить .ext
с помощью .png
, .jpg
и т.д.
Ответ 3
Мне нравится решение gauteh для его простоты, но оно имеет важный недостаток. Когда вы работаете на тысячах файлов, вы можете получить сообщение "слишком длинный список аргументов" (подробнее об этом), а во-вторых, script может очень медленно. В моем случае, запустив его примерно на 36 000 файлов, script переместился ок. один пункт в секунду! Я не совсем уверен, почему это происходит, но правило, которое я получил от коллег, было "find
- ваш друг".
find -name '*.jpg' | # find jpegs
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command
Для подсчета элементов и команды сборки используется gawk. Обратите внимание на основное отличие. По умолчанию find
выполняет поиск файлов в текущем каталоге и его подкаталогах, поэтому обязательно удаляйте поиск только в текущем каталоге (при необходимости используйте man find
).
Ответ 4
использование Pero-решения на OSX потребовало некоторой модификации. Я использовал:
find . -name '*.jpg' \
| awk 'BEGIN{ a=0 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' \
| bash
Примечание: обратная косая черта существует для продолжения строки
edit 20 июля 2015 года:
добавлена обратная связь @klaustopher для цитирования аргумента \"%s\"
команды mv
для поддержки имен файлов с пробелами.
Ответ 5
с командой "rename"
rename -N 0001 -X 's/.*/$N/' *.jpg
или
rename -N 0001 's/.*/$N.jpg/' *.jpg
Ответ 6
Очень простой bash один лайнер, который сохраняет исходные расширения, добавляет ведущие нули, а также работает в OSX:
num=0; for i in *; do mv "$i" "$(printf '%04d' $num).${i#*.}"; ((num++)); done
Упрощенная версия http://ubuntuforums.org/showthread.php?t=1355021
Ответ 7
Чтобы работать во всех ситуациях, поместите "\" для файлов с пробелом в имени
find . -name '*.jpg' | gawk 'BEGIN{ a=1 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' | bash
Ответ 8
Если ваш rename
не поддерживает -N
, вы можете сделать что-то вроде этого:
ls -1 -c | xargs rename -n 's/.*/our $i; sprintf("%04d.jpg", $i++)/e'
Изменить. Чтобы начать с определенного номера, вы можете использовать (несколько уродливый) код ниже, просто замените 123 на нужное число:
ls -1 -c | xargs rename -n 's/.*/our $i; if(!$i) { $i=123; } sprintf("%04d.jpg", $i++)/e'
Это список файлов по порядку по времени создания (в первую очередь, добавьте -r
в ls для обратного сортировки), затем отправляет этот список файлов для переименования. Переименовать использует Perl-код в регулярном выражении для форматирования и увеличения счетчика.
Однако, если вы имеете дело с изображениями JPEG с информацией EXIF, я бы рекомендовал exiftool
Это из документация exiftool в разделе "Переименование примеров"
exiftool '-FileName<CreateDate' -d %Y%m%d_%H%M%S%%-c.%%e dir
Rename all images in "dir" according to the "CreateDate" date and time, adding a copy number with leading '-' if the file already exists ("%-c"), and
preserving the original file extension (%e). Note the extra '%' necessary to escape the filename codes (%c and %e) in the date format string.
Ответ 9
В OSX установите переименование script из Homebrew:
brew install rename
Тогда вы можете сделать это очень смешно:
rename -e 's/.*/$N.jpg/' *.jpg
Или добавить красивый префикс:
rename -e 's/.*/photo-$N.jpg/' *.jpg
Ответ 10
Вы также можете использовать ls
ls *.JPG| awk 'BEGIN{ a=0 }{ printf "mv %s gopro_%04d.jpg\n", $0, a++ }' | bash
Ответ 11
Снова используя решение Pero с небольшим изменением, поскольку find
будет перемещаться по дереву каталогов в элементах заказа, хранятся в записях каталога. Это будет (в основном) быть последовательным от запуска до запуска на том же компьютере и по существу будет "порядком создания файла/каталога", если не было удалений.
Однако в некоторых случаях вам нужно получить некоторый логический порядок, например, по имени, которое используется в этом примере.
find -name '*.jpg' | sort -n | # find jpegs
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command
Ответ 12
У меня была аналогичная проблема и по этой причине написал оболочку script. Я решил опубликовать его независимо от того, что было опубликовано много хороших ответов, потому что я думаю, что это может быть полезно для кого-то. Не стесняйтесь улучшать его!
numerate
@Gnutt Поведение, которое вы хотите, может быть достигнуто, введя следующее:
./numerate.sh -d <path to directory> -o modtime -L 4 -b <startnumber> -r
Если опция -r
не указана, развертка будет только моделироваться (должно быть полезно для тестирования).
В тексте L описывается длина целевого числа (которое будет заполнено ведущими нулями)
также можно добавить префикс/суффикс с параметрами -p <prefix>
-s <suffix>
.
Если кто-то хочет, чтобы файлы были отсортированы численно, прежде чем они будут пронумерованы, просто удалите параметр -o modtime
.
Ответ 13
Предположим, что у нас есть эти файлы в каталоге, указанном в порядке создания, первый из которых является самым старым:
a.jpg
b.JPG
c.jpeg
d.tar.gz
e
тогда ls -1cr
выводит точно список выше. Затем вы можете использовать rename
:
ls -1cr | xargs rename -n 's/^[^\.]*(\..*)?$/our $i; sprintf("%03d$1", $i++)/e'
который выводит
rename(a.jpg, 000.jpg)
rename(b.JPG, 001.JPG)
rename(c.jpeg, 002.jpeg)
rename(d.tar.gz, 003.tar.gz)
Use of uninitialized value $1 in concatenation (.) or string at (eval 4) line 1.
rename(e, 004)
Предупреждение "использование неинициализированного значения [...]" отображается для файлов без расширения; вы можете игнорировать его.
Удалите -n
из команды rename
, чтобы применить переименование.
Этот ответ вдохновлен ответом Луке в апреле 2014 года. Он игнорирует требование Gnutts устанавливать количество ведущих нулей в зависимости от общего количества файлов.
Ответ 14
ls -1tr | rename -vn 's/.*/our $i;if(!$i){$i=1;} sprintf("%04d.jpg", $i++)/e'
переименовать -vn - удалить n для режима выключения теста
{$ я = 1;} - контрольный стартовый номер
"% 04d.jpg" - контрольный счетчик нуля 04 и установка расширения вывода .jpg
Ответ 15
a=1
for i in *.jpg; do
mv -- "$i" "$a.jpg"
a=`expr $a + 1`
done
Ответ 16
Большинство других решений будут перезаписывать существующие файлы, уже названные как число. Это особенно проблематично, если вы запускаете script, добавляете больше файлов и снова запускаете script.
Этот script сначала переименовывает существующие числовые файлы:
#!/usr/bin/perl
use strict;
use warnings;
use File::Temp qw/tempfile/;
my $dir = $ARGV[0]
or die "Please specify directory as first argument";
opendir(my $dh, $dir) or die "can't opendir $dir: $!";
# First rename any files that are already numeric
while (my @files = grep { /^[0-9]+(\..*)?$/ } readdir($dh))
{
for my $old (@files) {
my $ext = $old =~ /(\.[^.]+)$/ ? $1 : '';
my ($fh, $new) = tempfile(DIR => $dir, SUFFIX => $ext);
close $fh;
rename "$dir/$old", $new;
}
}
rewinddir $dh;
my $i;
while (my $file = readdir($dh))
{
next if $file =~ /\A\.\.?\z/;
my $ext = $file =~ /(\.[^.]+)$/ ? $1 : '';
rename "$dir/$file", sprintf("%s/%04d%s", $dir, ++$i, $ext);
}
Ответ 17
Этот oneliner перечисляет все файлы в текущем каталоге, сортирует по метке времени создания в обратном порядке (означает, что самый старый файл находится в начале) и автоматически переименовывается с конечными нулями в соответствии с количеством файлов. Расширение файла будет сохранено.
С годами у меня обычно есть только одна папка для фотографий и фильмов на мобильных телефонах. Применив эту команду, мои картинки и фильмы будут готовы для слайд-шоу в правильном порядке на телевизоре или в архиве.
Имейте в виду, что если у вас есть конфликты имен файлов, вы теряете файлы. Поэтому сначала переименуйте его в нечто странное, например, temp001.jpg
а затем выполните его до окончательного имени файла.
DIGITS=$(ls | wc -l | xargs | wc -c | xargs); ls -tcr | cat -n | while read n f; do mv "$f" "$(printf "%0${DIGITS}d" $n).${f##*.}"; done
Ответ 18
Для меня эта комбинация ответов сработала отлично:
ls -v | gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | bash
-
ls -v
помогает упорядочить 1 10 9 в правильном порядке: 1 9 10, избегая проблем с расширением имени файла с jpg JPG jpeg -
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }'
перенумеровывается с 4 символами и ведущими нулями. Избегая mv, я не пытаюсь случайно перезаписать все, что уже есть, случайно набрав тот же номер. -
bash
выполняет
Помните о том, что сказал @xhienne, передача неизвестного контента в bash представляет собой угрозу безопасности. Но это было не так для меня, поскольку я использовал свои отсканированные фотографии.
Ответ 19
Выполните команду переименовать все файлы в последовательность, а также расширение в нижнем регистре:
rename --counter-format 000001 --lower-case --keep-extension --expr='$_ = "$N" if @EXT' *
Ответ 20
Если вы используете аннотатор изображений для маркировки изображений.
$ make qt5py3
$ python3 labelImg.py
Ответ 21
Этот script будет сортировать файлы по дате создания в Mac OS bash. Я использую его для массового переименования видео. Просто измените расширение и первую часть имени.
ls -trU *.mp4| awk 'BEGIN{ a=0 }{ printf "mv %s lecture_%03d.mp4\n", $0, a++ }' | bash
Ответ 22
Здесь другое решение с командой "rename":
find -name 'access.log.*.gz' | sort -Vr | rename 's/(\d+)/$1+1/ge'
Ответ 23
Отсортировано по времени, ограничено jpg, ведущими нулями и базовым именем (в случае, если вы, вероятно, захотите):
ls -t *.jpg | cat -n | \
while read n f; do mv "$f" "$(printf thumb_%04d.jpg $n)"; done
(все в одной строке, без \
)
Ответ 24
Ответ Pero заставил меня здесь:)
Я хотел переименовать файлы относительно времени, так как зрители изображений не отображали изображения в порядке времени.
ls -tr *.jpg | # list jpegs relative to time
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command
Ответ 25
Чтобы перенумеровать 6000 файлов в одной папке, вы можете использовать опцию "Переименовать" в программе ACDsee.
Для определения префикса используйте этот формат: ####"*"
Затем установите стартовый номер и нажмите "Переименовать", и программа переименует все 6000 файлов с последовательными номерами.