- unixforum.org
- Переименование файлов по порядку (в командной строке bash)
- Переименование файлов по порядку
- Re: Переименование файлов по порядку
- Re: Переименование файлов по порядку
- Re: Переименование файлов по порядку
- Re: Переименование файлов по порядку
- Re: Переименование файлов по порядку
- Re: Переименование файлов по порядку
- Re: Переименование файлов по порядку
- Re: Переименование файлов по порядку
- Re: Переименование файлов по порядку
- Re: Переименование файлов по порядку
- Re: Переименование файлов по порядку
- Re: Переименование файлов по порядку
- Вывод файлов и нумерация
- Да, но нет
- Re: Да, но нет
- Переименование файлов и нумерация
- Вывод файла в терминале с нумерацией строк
- Команда nl
- Команда cat с ключом -n
unixforum.org
Переименование файлов по порядку (в командной строке bash)
Переименование файлов по порядку
Сообщение Maximus_V » 08.04.2008 21:33
Доброго вечера! Решил привести в порядок свой фотоальбом, для чего переименовать файлы изображений в каталогах, чтобы файлы имели название вида 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 » 08.04.2008 21:36
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.
Re: Переименование файлов по порядку
Сообщение Maximus_V » 08.04.2008 22:54
Все бы хорошо, но как быть в моем случае, когда операнд «что превращаем» для команды raname может быть абсолютно любым и разной длины? Например mama_na_dache.jpg papa_na_ogorode.jpg и т.п.? Как, используя rename, пронумеровать подобные файлы в 01.jpg . 20.jpg? Ведь этой команде нужно четко указать (или с использованием масок) что и во что переименовывать.
Я просто, будучи не силен в программировании, подумал, что можно будет объявить переменную каким-нибудь особым типом данных с указанием количества ведущих нулей.
Re: Переименование файлов по порядку
Сообщение ceeqwer » 08.04.2008 23:02
Ayanami-kun Сообщения: 532 Статус: Красноглазег ОС: Gentoo ~x86 with KDE 4.2.4
Re: Переименование файлов по порядку
Сообщение Ayanami-kun » 08.04.2008 23:03
Maximus_V
Можно сначала прогнать ваш цикл, а потом использовать rename ^_^
Это можно запихать в один скрипт.
Re: Переименование файлов по порядку
Сообщение k01 » 08.04.2008 23:06
i=0;for name in `ls *.jpg`; do i=$[i+1];mv $name `printf "%02d" $i`.jpg;done
Re: Переименование файлов по порядку
Сообщение /dev/random » 08.04.2008 23:07
x=10001 for i in `ls` do mv $i $.jpg (( x++ )) done
Re: Переименование файлов по порядку
Сообщение Maximus_V » 09.04.2008 07:32
x=10001 for i in `ls` do mv $i $.jpg (( x++ )) done
Re: Переименование файлов по порядку
Сообщение 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
Re: Переименование файлов по порядку
Сообщение sgfault » 16.09.2012 18:19
#!/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
Ага?
Другими словами, если не цепляться к ненужным точкам с запятой, ненужным cat и совершенно бесполезным перечитываниям файла $f при каждой итерации цикла, ваш скрипт просто не работает с именами файлов, содержащими пробел (и не только). И раз уж вы реснули тему 4-х летней давности ради того, чтобы выложить этот скрипт, потрудитесь его исправить.
Re: Переименование файлов по порядку
Сообщение Maximus_V » 17.09.2012 22:43
Интересный скрипт — насколько я понял, динамическая подстановка нужного количества ведущих нулей. Но спустя четыре года. это ж надо было постараться откопать!
Re: Переименование файлов по порядку
Сообщение Maximus_V » 17.09.2012 22:50
И раз тема живет, хочу добавить, что четыре года назад у меня не получилось загнать скрипт в одну строчку. А теперь — пожалуйста (вдруг кому пригодится еще через пять лет):
x=10001; for i in `ls`; do mv $i $.jpg; (( x++ )); done
Re: Переименование файлов по порядку
Сообщение sgfault » 18.09.2012 00:48
И раз тема живет, хочу добавить, что четыре года назад у меня не получилось загнать скрипт в одну строчку. А теперь — пожалуйста (вдруг кому пригодится еще через пять лет):
x=10001; for i in `ls`; do mv $i $.jpg; (( x++ )); done
Ну раз тема живет.. Ваш скрипт не работает с пробелами точно также, как и предыдущий, предложенный infra_hdc.
$ cat ../t.sh #!/bin/bash x=10001; for i in `ls`; do mv $i $.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
Вывод файлов и нумерация
Как через терминал вывести названия всех файлов из директории и пронумеровать их?
Чтобы получилось на выходе:
у меня точку после цифры не выводит
n=0; for i in *; do echo $((++n)). «$i»; done
Меньше байтов в строчке вовсе не означает, что это оптимальнее 🙂
Да, но нет
pve ~/tmp # ls|wc -l 80119 pve ~/tmp # time < n=0; for i in *; do echo $((++n)). "$i"; done; >> /dev/null real 0m0.414s user 0m0.412s sys 0m0.000s pve ~/tmp # time < ls|nl -s". "; >> /dev/null real 0m0.131s user 0m0.084s sys 0m0.048s
Вообще не самый грустный пример, вот «cat|while read. » это настоящий эпический трэш по производительности.
Re: Да, но нет
Кстати, если echo окажется внешней командой, то будет ещё намного медленнее.
Занятно, что у меня echo получилось в два раза всего увеличивает время выполнения, если в цикле поставить что-то тупое, типа a=$i. То есть тормозит не вызов syscall, а сам bash. Кто-бы сомневался. Ещё более солидное доказательство будет если в цикл засунуть формирование вывода в переменную для одного вызова echo, типа для начала как out=«$out $((++n). $i». Боже мой — оно в 10 раз тормознее стало.
Справедливости ради, замена на спец утилиты хорошо только тогда, когда вас это полностью устраивает. Ибо шаг в сторону от первоначального ТЗ — и приплыли, всё равно программить.
vodz ★★★★★ ( 05.07.17 16:57:07 MSK )
Последнее исправление: vodz 05.07.17 16:58:26 MSK (всего исправлений: 1)
Переименование файлов и нумерация
но выглядит как-то громоздко. Хотелось бы без создания временного файла обойтись. Что предложите в таком случае?
Это не громоздко. Громоздко — вот:
cat ~/bin/batchrename #!/bin/sh # this script wrote by Eddy # # batchrename - renames files like 01.ext, 02.ext . # # Создан 17-го Июля 2003 года в 20:35 # # format : batchrename # or: -r # -r - recoursively counter=0 extrec="" if [ "$#" -lt "1" ]; then echo -e "\n\t\tUsage:\n\tbatchrename [opt]\nopt:" echo -e "-r (or file list) -- renames recoursively ALL files" echo -e "\tin folder (or by file list given) with extension ." echo -e " -- renames ALL files in folder given" echo -e " -- renames ALL files of given filelist.\n\n" exit 0 fi Name="$*" if [ "$1" = "-r" ]; then extrec="$2" shift shift Name="$*" [ "$Name" = "" ] && Name="./" fi echo -e "\n\t\t\tRENAMING" del_dup for file in $Name do file=`echo "$file" | sed "s/<>/ /g"` if [ -d "$file" ];then echo -e "\nDiving into \033[38m $file \033[39m" cd "$file" if [ "$extrec" != "" ]; then batchrename -r $extrec `ls -1 | sed "s/\ /<>/g"` else batchrename `ls -1 | sed "s/\ /<>/g"` fi cd ../ continue fi ext=`ext "$file"` if [ "$ext" = "ion" ]; then continue fi if [ "$extrec" = "" -o "$ext" = "$extrec" ];then counter=`expr $counter + 1` echo -e "Progress: $counter files\r\c" mv "$file" "rnmd$counter.$ext" fi done echo -e "\n\n\t\t\tENDING" digits=`echo $counter|awk ''` cnt=1 while [ $digits -gt $cnt ] do f=`ls -S -1|grep "rnmd2\\."` rename rnmd rnmd0 $f cnt=`expr $cnt + 1` done if [ "$counter" -gt "0" ]; then rename rnmd "" rnmd* fi echo -e "\n\t\t\tDone . \n"
mkdir tmp && cd tmp for i in a b c d; do touch file.b$i; done n=0; for i in *; do let n=n+1; mv $i $(echo $i | sed -e "s/\./$n\./"); done
Вывод файла в терминале с нумерацией строк
Расскажу о двух простых способах вывода текстового файла в терминале с отображением номеров строк. Это может быть полезно, например, программистам или тем, кто много работает с конфигурационными файлами, используя терминал в Linux.
Для теста я буду использовать файл следующего содержания, содержащий 4 строки:
Строка номер один Строка номер три Строка номер четыре
Вторая строка в файле пустая.
Команда nl
В простейшем случае для команды nl необходимо указать имя файла:
В результате на экран будет выведено содержимое файла, а слева будут стоять номера строк:
$ nl textfile 1 Строка номер один 2 Строка номер три 3 Строка номер четыре
Обратите внимание, что пустую строку в файле команда nl проигнорировала. Для того, чтобы учитывались все строки используется ключ -ba:
$ nl -ba textfile 1 Строка номер один 2 3 Строка номер три 4 Строка номер четыре
Команда nl поддерживает различные форматы вывода (стили) и некоторые дополнительные опции. Для получения справки выполните:
Команда cat с ключом -n
У команды cat есть аргумент -n, который предназначен для вывода файла с нумерацией строк. Выполним:
cat -n textfile 1 Строка номер один 2 3 Строка номер три 4 Строка номер четыре
Мы получили аналог выполнения nl -ba textfile. Для пропуска пустых строк необходимо использовать ключ -b: