Переименование файлов в папке в последовательные номера
Я хочу переименовать файлы в каталоге в последовательные номера. На основе даты создания файлов.
sadf.jpg
до 0001.jpg
, wrjr3.jpg
to 0002.jpg
и так далее, количество ведущих нулей в зависимости от общего объема файлов (нет необходимости в дополнительных нулей, если они не нужны). 23 ответов
попробуйте использовать цикл, 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
флаг предотвращает автоматическую перезапись существующих файлов.
красота в одной строке
ls | cat -n | while read n f; do mv "$f" "$n.extension"; done
изменить расширение с желаемым PNG, Jpg или некоторыми другими.
мне нравится решение gauteh за его простоты, но он имеет важный недостаток. При работе с тысячами файлов вы можете получить сообщение "список аргументов слишком длинный" (подробнее об этом), а во-вторых, сценарий может быть очень медленным. В моем случае, запустив его примерно на 36.000 файлах, скрипт переместился ок. один предмет в секунду! Я не совсем уверен, почему это происходит, но правило, которое я получил от коллег "find
- ваш друг".
find -name '*.jpg' | # find jpegs
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", , a++ }' | # build mv command
bash # run that command
count элементов и построить команду,gawk. Обратите внимание на главное отличие. По умолчанию find
поиск файлов в текущем каталоге и его подкаталогах, поэтому при необходимости ограничьте поиск только в текущем каталоге (используйте man find
чтобы увидеть, как).
использование решения Pero на OSX потребовало некоторой модификации. Я использовал:
find . -name '*.jpg' \
| awk 'BEGIN{ a=0 }{ printf "mv \"%s\" %04d.jpg\n", , a++ }' \
| bash
Примечание: обратные косые черты существуют для продолжения строки
редактировать 20 июля 2015:
incorporated @ klaustopher's обратная связь, чтобы процитировать на mv
команда для поддержки имен файлов с пробелами.
очень простой bash один лайнер, который сохраняет исходные расширения, добавляет ведущие нули, а также работает в OSX:
num=0; for i in *; do mv "$i" "$(printf '%04d' $num).${i#*.}"; ((num++)); done
упрощенная версия http://ubuntuforums.org/showthread.php?t=1355021
чтобы работать во всех ситуациях, поставьте \ " для файлов, которые имеют место в имени
find . -name '*.jpg' | gawk 'BEGIN{ a=1 }{ printf "mv \"%s\" %04d.jpg\n", , a++ }' | bash
если 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-код в regex для формат и инкремент счетчик.
однако, если вы имеете дело с 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.
на OSX, установите скрипт переименования из Homebrew:
brew install rename
затем вы можете сделать это очень легко:
rename -e 's/.*/$N.jpg/' *.jpg
или добавить префикс:
rename -e 's/.*/photo-$N.jpg/' *.jpg
вы также можете использовать ls
ls *.JPG| awk 'BEGIN{ a=0 }{ printf "mv %s gopro_%04d.jpg\n", , a++ }' | bash
у меня была аналогичная проблема, написал скрипт по этой причине. Я решил опубликовать его независимо от того, что многие хорошие ответы уже были опубликованы, потому что я думаю, что это может быть полезно для кого-то. Не стесняйтесь улучшать его!
@Gnutt поведение, которое вы хотите, может быть достигнуто путем ввода следующего:
./numerate.sh -d <path to directory> -o modtime -L 4 -b <startnumber> -r
если параметр -r
исключено, что развертывание будет только моделироваться (должно быть полезно для тестирование.)
otion L описывает длину целевого числа (которое будет заполнено ведущими нулями)
также можно добавить префикс / суффикс с параметрами -p <prefix>
-s <suffix>
.
если кто-то хочет, чтобы файлы были отсортированы численно, прежде чем они будут пронумерованы, просто удалите .
предположим, что у нас есть эти файлы в каталоге, перечисленные в порядке создания, первый из которых является самым старым:
a.jpg
b.JPG
c.jpeg
d.tar.gz
e
затем ls -1cr
выводит точно список выше. Затем вы можете использовать rename
:
ls -1cr | xargs rename -n 's/^[^\.]*(\..*)?$/our $i; sprintf("%03d", $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 in concatenation (.) or string at (eval 4) line 1.
rename(e, 004)
предупреждение "использование неинициализированного значения [ ... ]" отображается для файлов без расширения; его можно игнорировать.
удалить -n
С rename
команда для фактического применения переименование.
этот ответ навеян ответ Люка от апреля 2014. Он игнорирует требование Gnutt установить количество ведущих нулей в зависимости от общего количества файлов.
снова используя решение перо с небольшим изменением, потому что find
будет проходить по дереву каталогов в порядке, элементы которого хранятся в записях каталога. Это будет (в основном) согласовано от запуска к запуску на одной машине и по существу будет "порядок создания файла/каталога", если не было удалений.
однако в некоторых случаях вам нужно получить некоторый логический порядок, скажем, по имени, который используется в этом примере.
find -name '*.jpg' | sort -n | # find jpegs
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", , a++ }' | # build mv command
bash # run that command
большинство других решений перезапишут существующие файлы, уже названные числом. Это особенно проблема при запуске сценария, добавлении дополнительных файлов и повторном запуске сценария.
этот скрипт переименовывает существующие числовые файлы:
#!/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 =~ /(\.[^.]+)$/ ? : '';
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 =~ /(\.[^.]+)$/ ? : '';
rename "$dir/$file", sprintf("%s/%04d%s", $dir, ++$i, $ext);
}
этот 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
ls -1tr | rename -vn 's/.*/our $i;if(!$i){$i=1;} sprintf("%04d.jpg", $i++)/e'
переименовать-vn - удалить n для выключения тестового режима
{$i=1;} - контроль стартовый номер
"%04d.jpg" - контроля ноль 04 и установить расширение производства .формат JPG
для меня эта комбинация ответов отлично работал:
ls -v | gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", , a++ }' | bash
-
ls -v
помогает при заказе 1 10 9 в правильном порядке: 1 9 10, избегая проблем с расширением файла с jpg JPG jpeg -
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", , a++ }'
перенумеровать с 4 символами и ведущими нулями. Избегая mv, я случайно не пытаюсь перезаписать что-либо, что уже есть, случайно имея тот же номер. -
bash
выполняет
имейте в виду, что @xhienne сказал, что передача неизвестного контента в bash является угрозой безопасности. Но это было не так для меня, поскольку я использовал свои отсканированные фотографии.
этот скрипт будет сортировать файлы по дате создания на Mac OS bash. Я использую его для массового переименования видео. Просто измените расширение и первую часть имени.
ls -trU *.mp4| awk 'BEGIN{ a=0 }{ printf "mv %s lecture_%03d.mp4\n", , a++ }' | bash
здесь другое решение с командой" переименовать":
find -name 'access.log.*.gz' | sort -Vr | rename 's/(\d+)/+1/ge'
сортировка по времени, ограниченная jpg, ведущими нулями и базовым именем (если вы, вероятно, захотите):
ls -t *.jpg | cat -n | \
while read n f; do mv "$f" "$(printf thumb_%04d.jpg $n)"; done
(все на одной строке, без \
)
для перенумерования 6000 файлов в одной папке вы можете использовать опцию "переименовать" программы ACDsee.
для определения префикса используйте следующий формат:####"*"
затем установите начальный номер и нажмите переименовать, и программа переименует все 6000 файлов с последовательными номерами.
ответ перо привел меня сюда:)
Я хотел переименовать файлы относительно времени, поскольку просмотрщики изображений не отображали изображения в порядке времени.
ls -tr *.jpg | # list jpegs relative to time
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", , a++ }' | # build mv command
bash # run that command