Переименование файлов по порядку (в командной строке bash)

Для новичков как вообще в Linux, так и в конкретной теме, к которой относится вопрос.

Модератор: Bizdelnick

Аватара пользователя
Maximus_V
Сообщения: 432
ОС: Gentoo, FreeBSD

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

Сообщение Maximus_V »

Доброго вечера! Решил привести в порядок свой фотоальбом, для чего переименовать файлы изображений в каталогах, чтобы файлы имели название вида 01.jpg 02.jpg и т.д. (короче, по порядку)
Нагуглил такую команду:

Код: Выделить всё

x=1; for i in `ls`; do mv $i $x'.jpg'; x=$(($x+1)); done

Если файлов меньше 10, то все нормально. Если же файлов 10 или более, то хотелось бы переименовывать их так, чтобы впереди был ведущий нуль, для удобства просмотра.
Вопрос - как изменить команду, чтобы при переименовании появлялся ведущий нуль?
Спасибо сказали:
Аватара пользователя
Ayanami-kun
Сообщения: 532
Статус: Красноглазег
ОС: Gentoo ~x86 with KDE 4.2.4

Re: Переименование файлов по порядку

Сообщение Ayanami-kun »

Выдержка из man rename

Код: Выделить всё

       For example, given the files
              foo1, ..., foo9, foo10, ..., foo278, the commands

              rename foo foo0 foo?
              rename foo foo0 foo??

       will turn them into foo001, ..., foo009, foo010, ..., foo278.


Очень удобная утилита....

hint: rename <что превращаем> <во что превращаем> <файлы>
Спасибо сказали:
Аватара пользователя
Maximus_V
Сообщения: 432
ОС: Gentoo, FreeBSD

Re: Переименование файлов по порядку

Сообщение Maximus_V »

Все бы хорошо, но как быть в моем случае, когда операнд "что превращаем" для команды raname может быть абсолютно любым и разной длины? Например mama_na_dache.jpg papa_na_ogorode.jpg и т.п.? Как, используя rename, пронумеровать подобные файлы в 01.jpg ... 20.jpg? Ведь этой команде нужно четко указать (или с использованием масок) что и во что переименовывать...
Я просто, будучи не силен в программировании, подумал, что можно будет объявить переменную каким-нибудь особым типом данных с указанием количества ведущих нулей...
Спасибо сказали:
Аватара пользователя
ceeqwer
Сообщения: 29
ОС: Ubuntu Linux

Re: Переименование файлов по порядку

Сообщение ceeqwer »

В гноме есть gThumb
Ubuntu - Linux for human beings
Спасибо сказали:
Аватара пользователя
Ayanami-kun
Сообщения: 532
Статус: Красноглазег
ОС: Gentoo ~x86 with KDE 4.2.4

Re: Переименование файлов по порядку

Сообщение Ayanami-kun »

Maximus_V
Можно сначала прогнать ваш цикл, а потом использовать rename ^_^
Это можно запихать в один скрипт...
Спасибо сказали:
Аватара пользователя
k01
Сообщения: 104
ОС: Archlinux

Re: Переименование файлов по порядку

Сообщение k01 »

можно использовать команду printf например так:

Код: Выделить всё

i=0;for name in `ls *.jpg`; do i=$[i+1];mv $name `printf "%02d" $i`.jpg;done
Рациональное программирование — наш ответ MicroSoft!
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5403
ОС: Gentoo

Re: Переименование файлов по порядку

Сообщение /dev/random »

Простой способ сделать ведущие нули:

Код: Выделить всё

x=10001
for i in `ls`
do
    mv $i ${x:1}.jpg
    (( x++ ))
done
Спасибо сказали:
Аватара пользователя
Maximus_V
Сообщения: 432
ОС: Gentoo, FreeBSD

Re: Переименование файлов по порядку

Сообщение Maximus_V »

/dev/random писал(а):
08.04.2008 23:07
Простой способ сделать ведущие нули:

Код: Выделить всё

x=10001
for i in `ls`
do
    mv $i ${x:1}.jpg
    (( x++ ))
done

Спасибо, то что нужно! Решено.
Спасибо сказали:
Аватара пользователя
infra_hdc
Сообщения: 376
ОС: GNU/Linux

Re: Переименование файлов по порядку

Сообщение infra_hdc »

попробуйте вот так:

Код: Выделить всё

#!/bin/bash
f=$(mktemp); ls -1 >$f; n=$(cat $f | wc -l);
for i in $(seq -w 1 $n) ; do
    s=$(cat $f | head -$i | tail -1);
    mv $s $i.jpg;
done;
rm -f $f
Спасибо сказали:
Аватара пользователя
sgfault
Сообщения: 586
Статус: -

Re: Переименование файлов по порядку

Сообщение sgfault »

infra_hdc писал(а):
08.09.2012 12:29
попробуйте вот так:

Код: Выделить всё

#!/bin/bash
f=$(mktemp); ls -1 >$f; n=$(cat $f | wc -l);
for i in $(seq -w 1 $n) ; do
    s=$(cat $f | head -$i | tail -1);
    mv $s $i.jpg;
done;
rm -f $f

Мимо проходил.

Код: Выделить всё

$ touch 'a b.jpg'
$ cat ../t.sh
#!/bin/bash

f=$(mktemp); ls -1 >$f; n=$(cat $f | wc -l);
for i in $(seq -w 1 $n) ; do
    s=$(cat $f | head -$i | tail -1);
    mv $s $i.jpg;
done;
rm -f $f
$ ../t.sh
mv: target `1.jpg' is not a directory

Ага? :happy:
Другими словами, если не цепляться к ненужным точкам с запятой, ненужным cat и совершенно бесполезным перечитываниям файла $f при каждой итерации цикла, ваш скрипт просто не работает с именами файлов, содержащими пробел (и не только). И раз уж вы реснули тему 4-х летней давности ради того, чтобы выложить этот скрипт, потрудитесь его исправить.
Спасибо сказали:
Аватара пользователя
Maximus_V
Сообщения: 432
ОС: Gentoo, FreeBSD

Re: Переименование файлов по порядку

Сообщение Maximus_V »

Интересный скрипт - насколько я понял, динамическая подстановка нужного количества ведущих нулей. Но спустя четыре года... это ж надо было постараться откопать!
Спасибо сказали:
Аватара пользователя
Maximus_V
Сообщения: 432
ОС: Gentoo, FreeBSD

Re: Переименование файлов по порядку

Сообщение Maximus_V »

И раз тема живет, хочу добавить, что четыре года назад у меня не получилось загнать скрипт в одну строчку. А теперь - пожалуйста (вдруг кому пригодится еще через пять лет):

Код: Выделить всё

x=10001; for i in `ls`; do mv $i ${x:1}.jpg; (( x++ )); done
Можно исполнять прямо из командной строки bash
Спасибо сказали:
Аватара пользователя
sgfault
Сообщения: 586
Статус: -

Re: Переименование файлов по порядку

Сообщение sgfault »

Maximus_V писал(а):
17.09.2012 22:50
И раз тема живет, хочу добавить, что четыре года назад у меня не получилось загнать скрипт в одну строчку. А теперь - пожалуйста (вдруг кому пригодится еще через пять лет):

Код: Выделить всё

x=10001; for i in `ls`; do mv $i ${x:1}.jpg; (( x++ )); done
Можно исполнять прямо из командной строки bash

Ну раз тема живет.. Ваш скрипт не работает с пробелами точно также, как и предыдущий, предложенный infra_hdc.

Код: Выделить всё

$ cat ../t.sh
#!/bin/bash

x=10001;
for i in `ls`; do
    mv $i ${x:1}.jpg;
    (( x++ ));
done
$ touch 'a b a.jpg' a.jpg
$ ll
total 0
-rw-r----- 1 sgf sgf 0 Sep 18 00:43 a b a.jpg
-rw-r----- 1 sgf sgf 0 Sep 18 00:43 a.jpg
$ ../t.sh
mv: cannot stat `a': No such file or directory
mv: cannot stat `b': No such file or directory
mv: cannot stat `a.jpg': No such file or directory
$ ll
total 0
-rw-r----- 1 sgf sgf 0 Sep 18 00:43 0003.jpg
-rw-r----- 1 sgf sgf 0 Sep 18 00:43 a b a.jpg

Обратите внимание, что файл a.jpg вместо номера 0002 получил 0003.

Или более хитрый вариант:

Код: Выделить всё

$ touch a.jpg b.jpg '*.jpg'
$ ll
total 0
-rw-r----- 1 sgf sgf 0 Sep 18 00:10 a.jpg
-rw-r----- 1 sgf sgf 0 Sep 18 00:10 b.jpg
-rw-r----- 1 sgf sgf 0 Sep 18 00:10 *.jpg
$ ../t.sh
mv: cannot stat `a.jpg': No such file or directory
mv: cannot stat `b.jpg': No such file or directory
mv: target `0005.jpg' is not a directory
$ ll
total 0
-rw-r----- 1 sgf sgf 0 Sep 18 00:10 0001.jpg
-rw-r----- 1 sgf sgf 0 Sep 18 00:10 0002.jpg
-rw-r----- 1 sgf sgf 0 Sep 18 00:10 *.jpg

и этот пример имеет весьма интересное продолжение. Запустим еще раз

Код: Выделить всё

$ ../t.sh
mv: `0001.jpg' and `0001.jpg' are the same file
mv: `0002.jpg' and `0002.jpg' are the same file
mv: target `0005.jpg' is not a directory
sgf@shilvana:.../tmp/t$ ll
total 0
-rw-r----- 1 sgf sgf 0 Sep 18 00:17 0003.jpg
-rw-r----- 1 sgf sgf 0 Sep 18 00:17 0004.jpg
-rw-r----- 1 sgf sgf 0 Sep 18 00:17 *.jpg

Видите? Номера сдвинулись вверх.

Придумать можно и более реалистичные варианты, но есть ли смысл? Даже этих примеров достачно, чтобы сказать, что последствия запуска скрипта на чем-то, кроме букв и, возможно, цифр, непредсказуемы.

Upd. Вообще, сдвиг номеров можно получить значительно проще:

Код: Выделить всё

$ touch 0001.jpg '*.jpg'
$ ll
total 0
-rw-r----- 1 sgf sgf 0 Sep 18 00:51 0001.jpg
-rw-r----- 1 sgf sgf 0 Sep 18 00:51 *.jpg
$ ../t.sh
mv: `0001.jpg' and `0001.jpg' are the same file
mv: target `0003.jpg' is not a directory
$ ll
total 0
-rw-r----- 1 sgf sgf 0 Sep 18 00:51 0002.jpg
-rw-r----- 1 sgf sgf 0 Sep 18 00:51 *.jpg

Файд 0001 был переименован в 0002.
Спасибо сказали: