Краткий справочник по массовому переименовыванию файлов :-)


ramok аватар

ramok - Posted on 01 Август 2007

Иногда нужно производить массовые переименования файлов. Изучая командную строку юникса когда то, меня удивило отсутствие такой приятной возможности в DOS как массовые переименовывания файлов (помню было что то типа copy *.c *.bak).

1. По первому разу я просто в vi создавал множество команд mv производящие нужные действия. Самый очевидный, и самый трудоемкий путь Ж:-)

2. Позже я начал разбираться с командной строкой юникса и мог запрограммировать массовые переименования.

for i in *.c; do
  mv $i `echo $i | sed 's/\.c$/.bak/'`
done

в sed задается то как хочется переименовать файл.

Вариант для zsh

for i (*.c) mv $i $i:r.bak

3. Как оказалось позже в поставке perl имеется простенькая утилитка rename. Первым параметром можно указать кусочек кода на perl который применяется к каждому имени файла переданные как параметры.

$ rename 's/\.c\.orig$/.c/' *.c # переименовать все *.c.orig в *.c
$ rename 'y/A-Z/a-z/' *.JPG     # имена фотографий маленькими буквами
$ rename 's/\U/\u/g' *.JPG      # тоже самое
$ rename '$_=lc' *              # тоже самое, но для всех файлов
$ rename 's/deftones-//' *.mp3  # убрать префис 'deftones-' у *.mp3
$ rename 's/^/jerk-/' *.swf     # добавить префикс 'jerk-' у *.swf
$ rename 's/ /_/g' *            # пробелы в именах файлах заменить на '_'
# перевести в большой регистр часть имени файла
$ rename -v 's/s\d.*e\d/\U$&\E/' House.M.D.s0*  
House.M.D.s03e04.rus.avi renamed as House.M.D.S03E04.rus.avi
House.M.D.s03e05.rus.avi renamed as House.M.D.S03E05.rus.avi
House.M.D.s03e06.rus.avi renamed as House.M.D.S03E06.rus.avi
House.M.D.s03e07.rus.avi renamed as House.M.D.S03E07.rus.avi

# более сложный вариант by mancubus.

rename 'tr/ /_/;$_=lc' *      # переводит все файлы в директории в
                                     # нижний регистр и заменяет " " на _

4. В zsh есть модуль zmv который как раз и занимается подобными преобразованиями.
Это довольно таки сложная в использовании команда, и думаю только zsh-гуру могут в полной мере ей пользоваться Ж:-)
Но тем не менее сами разработчики предлагают сделать пару довольно таки удобных алиасов, которые ведут себя
так же как команды copy и move в DOS.

Достаточно в ~/.zshrc прописать.

autoload zmv
alias ccp='noglob zmv -CW'
alias mmv='noglob zmv -W'

noglob перед командой обозначает что * не будет пребразован в имена файлов.

ccp *.c *.bak          # для каждого файла с расширением .c создается копия с расширением .bak
mmv **/*.jpeg **/*.jpg # переименовывает файлы .jpeg во всех вложенных директориях в .jpg
zmv -v '(* *)' '${1// /_}' # в файлах в которых есть пробелы,заменить на '_' и вывести полученые имена

Маньяки могут почитать комментарии в начале скрипта для всех возможностей.
/usr/share/zsh/**/zmv

PS отдельное спасибо товарищу mancubus за то что пнул меня дописать эту статью Ж:-)

5
Ваша оценка: Ничего Рейтинг: 5 (1 vote)

$ ls *.zip | sed  -r "s/^(.*)\.zip$/mv \1.zip _\1.rar/" | sh

Normally I do not read article on blogs, however I would like to say that this write-up very
forced me to check out and do so! Your writing style has been surprised me.
Thanks, quite great post.

Переименовать имя файла в команду переименования данного файла и вернуть это шеллу... Поразительно изящное решение

Скриптик для переименования кириллических имен файлов в руглиш:

#!/usr/bin/perl
 
@ARGV || die " Usage:
    scriptname файл1 файл2 ...
    scriptname \"имя файла\" ...
    scriptname имя\\ файла ...
    scriptname \*.mp3
    scriptname \*";
 
sub translit
{
    my $text = shift;
    $text =~ y/ абвгдеёзийклмнопрстуфхъыьэ/_abvgdeezijklmnoprstufh'y'e/;
    $text =~ y/АБВГДЕЁЗИЙКЛМНОПРСТУФХЪЫЬЭ/ABVGDEEZIJKLMNOPRSTUFH'Y'E/;
    my %mchars = ('ж'=>'zh','ц'=>'tz','ч'=>'ch','ш'=>'sh','щ'=>'sch','ю'=>'ju','я'=>'ja',
                  'Ж'=>'ZH','Ц'=>'TZ','Ч'=>'CH','Ш'=>'SH','Щ'=>'SCH','Ю'=>'JU','Я'=>'JA');
    for my $c (keys %mchars) {
        $text =~ s/$c/$mchars{$c}/g;
    }
    return $text;
}
 
while (@ARGV)
{
  rename($ARGV[0],translit($ARGV[0])) || die "Can't rename $ARGV[0] to translit($ARGV[0]): $!";
  shift;
}

ЗЫ: А еще ЕМНИП вроде был патч к convmv - добавление кодировки руглиш...

I'm not sure exactly why but this weblog is loading incredibly slow for me.

Is anyone else having this problem or is it a problem on my end?

I'll check back later on and see if the problem still exists.

Thanks for sharing your info. I truly appreciate your efforts and I am waiting
for your next post thanks once again.

Hey there just wanted to give you a quick heads up.
The words in your content seem to be running off the screen in Internet explorer.
I'm not sure if this is a formatting issue or something
to do with web browser compatibility but I thought I'd post to let you know.
The layout look great though! Hope you get the problem solved soon. Kudos

у меня utf-8 и результат не впечатлял

$ touch файл && ./z файл
$ ls -l
-rw-rw-r-- 1 ramok ramok     0 Май 31 13:35 meabauay
-rwxrwxr-x 1 ramok ramok   894 Май 31 13:41 z*

Заработало, после того как сохранил скрипт в koi-8, и добавил принудительную перекодировку имени файла в koi-8

#!/usr/bin/perl 
 
use Text::Iconv;
 
@ARGV || die " Usage:
    scriptname file1 file2 ...
    scriptname \"file name\" ...
    scriptname file\\ name ...
    scriptname \*.mp3
    scriptname \*";
 
sub translit
{
    my $text = shift;
    $text = Text::Iconv->new("","koi-8")->convert($text);
    $text =~ y/ абвгдеёзийклмнопрстуфхъыьэ/_abvgdeezijklmnoprstufh'y'e/;
    $text =~ y/АБВГДЕЁЗИЙКЛМНОПРСТУФХЪЫЬЭ/ABVGDEEZIJKLMNOPRSTUFH'Y'E/;
    my %mchars = ('ж'=>'zh','ц'=>'tz','ч'=>'ch','ш'=>'sh','щ'=>'sch','ю'=>'ju','я'=>'ja',
                  'Ж'=>'ZH','Ц'=>'TZ','Ч'=>'CH','Ш'=>'SH','Щ'=>'SCH','Ю'=>'JU','Я'=>'JA');
 
    map {$text =~ s/$_/$mchars{$_}/g} (keys %mchars);
 
    return $text;
}
 
while (@ARGV)
{
  rename($ARGV[0],translit($ARGV[0])) || die "Can't rename $ARGV[0] to translit($ARGV[0]): $!";
  shift;
}

За одно вместо for использовал map.
Спасибо!

PS
кстати линка в тему

I was curious if you ever thought of changing the page layout of your blog?
Its very well written; I love what youve got to say.
But maybe you could a little more in the way of content
so people could connect with it better. Youve got an awful lot of text for only having 1 or 2 pictures.
Maybe you could space it out better?

За map - спасибо, как-то протупил ;-))
Да, скриптик писался для неUTFной раскладки... Не знаю как в случае Text::Iconv, но iconv без -c спотыкается на недопустимых символах... Так что тут надо быть осторожным ;-))
А для UTFной - нечто такое:

#!/bin/bash
IFS='|';for i in `ls -1|sed -n 'H;${x;s/\n/\|/g;p}'` ; do mv -i $i  $(echo -n $i | sed -e "s/[\:,\`\'\"\{\}]//g;s/\!\[\]\(\)\@\#\$\%\^\*\+\~\;\<\>\?]//g;s/ё/e/;s/Ё/E/;s/ж/zh/;s/Ж/ZH/;s/ц/tz/;s/Ц/TZ/;s/ч/ch/;s/Ч/CH/;s/ш/sh/g;s/Ш/SH/;s/щ/s4/;s/Щ/S4/;s/ю/ju/;s/Ю/JU/;s/я/ja/;s/Я/JA/;s/&/_and_/" | sed 'y/[абвгдезийклмнопрстуфхъыьэ АБВГДЕЗИЙКЛМНОПРСТУФХЪЫЬЭ]/[abvgdezijklmnoprstufxjyje-ABVGDEZIJKLMNOPRSTUFXJYJE]/') ; done

Ссылка вернула память - все попутал %-)) Речь не о convmv, а об iconv. Руглиш (весьма отвратненький, правда) им можно сделать примерно так:

cat sometext | iconv -f utf8 -t koi-7//TRANSLIT | tr 'a-zA-Z' 'A-Za-z'

ЗЫ: Еще способ "перекодировки" (некая альтернатива convmv): свежевышедший Midnight Commander умеет по ALT-e менять кодировку прямо на файловой панели. Устанавливаем на панелях нужные кодировки и далее F5 или F6...

Hi, I wish for to subscribe for this weblog to take most up-to-date updates,
therefore where can i do it please help out.

This is my first time pay a visit at here and i am truly pleassant to read everthing at single place.

Уважаемые гуру.

Зачем такие сложности? :-)

В Delphin находите нужную папку с файлами в которых полный бардак.
Выделяете все файлы "Правка" > "Выделить всё"> в окне курсором мышки становитесь на выделенное, при нажатии правой кнопки мыши появляется меню, выбираете "Перименовать", появляется окошко в котором написано "объект" и #. Вместо объекта ставите все что хотите и нажимете ОК и будет вам счастье переименованное с 1 и до......

Hey very cool site!! Man .. Beautiful .. Wonderful ..

I will bookmark your blog and take the feeds also? I'm satisfied to find a
lot of helpful info right here within the put up, we need work out more strategies
in this regard, thank you for sharing. . . .
. .

I’m not that much of a internet reader to be honest but your sites really nice, keep it up!

I'll go ahead and bookmark your site to come back down the road.
Many thanks

Fantastic beat ! I wish to apprentice while you amend
your site, how can i subscribe for a blog website? The account aided me a acceptable
deal. I had been tiny bit acquainted of this your broadcast
provided bright clear idea

Gut gemacht!!!! +1

Да забыл, по поводу десяток и сотен, как я с ними борюсь. Я делаю так, что бы небыло бардака с десятками сотнями и так далее, я в место "объект" ставлю нужное колличество нулей и # а далее все путем :-)

Во-первых подписыватся принято с конце сообщения, а не прямо в заголовке Ж:-)
Во-вторых не совсем понятно к чему этот коментарий: к статье или к ветке коментариев о пронумеровывании файлов?
В-третьих может стоило бы реальных примеров добавить, а лучше со скриншотами (я так понимаю Delphin это какая то GUI программа).
Идеи для примеров можно брать прямо из статьи:

  • Изменить расширения файлов
  • Пронумеровать файлы
  • Перевести имена файлов в большой/малый регистры
  • Убрать префикс или суффикс у файлов
  • и так далее..
Тогда это был бы не только критический, но и полезный коментарий Ж:-)

вместо

cp ReallyVeryLongFileNameYouDontWantToTypeTwice ReallyVeryLongFileNameYouDontWantToTypeTwice.bak

пишем

cp ReallyVeryLongFileNameYouDontWantToTypeTwice{,.bak}

взято здесь

из кучи файлов с различными именами, допустим расширением *.gif требуется привести к такому виду:
image001.gif
image002.gif
...
imageNNN.gif

Хотя это очень востребовано, но ненагугливается красивое решение...

x=1; for i in *.gif ; do mv $i image$x.gif;x=$(($x+1)); done

Жаль что начальные нули не подставляет, т.е. вид:
image1.gif
image2.gif
...
image999.gif

Что потом, при сортировке, будет вразброс...

x=1000; for i in *.gif ; do mv $i image$x.gif;x=$(($x+1)); done

Hello Dear, are you genuinely visiting this site on a
regular basis, if so after that you will without doubt get
fastidious experience.

Spot on with this write-up, I truly feel this website needs
much more attention. I'll probably be returning to read more,
thanks for the information!

с помощью rename от перла

$ rename 'no strict; $_=sprintf "image%03d.gif",$i++' *.gif

Wonderful blog you have here but I was wondering if you knew of any forums that cover the same topics talked about
here? I'd really love to be a part of group where I can get
advice from other knowledgeable individuals that share the same interest.
If you have any recommendations, please let me know. Kudos!

на вскидку

x=1; for i in *.gif ; do mv $i image$(printf "%03d" $x).gif;x=$(($x+1)); done

Почему-то никто не написал способ для find. Однако он тоже может команды исполнять.

К примеру тупое переименование всех файлов в каталоге

$ find . * -exec mv {} {}.bak \;

за одно переименует все что во вложенных каталогах Ж:-)

ps
* помоему лишнее?
{} вроде надо квотировать
--
Signature invent in progress 24% ##........

>за одно переименует все что во вложенных каталогах Ж:-)

Только в текущем:
-maxdepth 1

>* помоему лишнее?
+1

>{} вроде надо квотировать
ИМХО нет

добавлено:
Виноват, квотировать нужно

I really like your blog.. very nice colors & theme.
Did you create this website yourself or did you hire someone to do it for you?
Plz respond as I'm looking to design my own blog and would
like to find out where u got this from. many thanks

wonderful submit, very informative. I ponder
why the opposite specialists of this sector do not understand this.
You should proceed your writing. I'm confident,
you have a huge readers' base already!

Hello There. I found your blog using msn. This is an extremely well written article.

I'll be sure to bookmark it and return to read more of your useful information. Thanks
for the post. I'll certainly return.

What's up everybody, here every one is sharing these kinds of know-how, thus it's good to read this web site, and I used to go to see this web site
daily.

А я через mc копирую/переименовываю. Выделяешь нужные файлы, жмёшь F5 или F6, в источнике пишешь:
*.c
а в приемнике:
*.bak

И всё. Или, например, поменять местами имя и расширение:
*.*
\2.\1

Только метасимволы шелл галочка должна быть включена для обоих примеров. Если её выключить, то там чуть сложнее, но зато гибче. Короче F1 в помошь :)

1) Дополнение к трудоёмкому способу :

for i in *.c; do
  mv "$i" "${i%.c}.bak"
done

2) Насчёт rename из состава perl: огромное спасибо, раньше не знал, что там можно любые команды писать; использовал только s для замены :D. Кстати, с русскими буквами это не сработает. Если локаль не utf8, то можно сделать так:

rename 'use locale; tr/ /_/;$_=lc' *

Но если utf8 - не работает. Есть идеи?

3) Не совсем в тему, но тем не менее:

Для массового переименования файлов между разными кодировками есть convmv

Hi there! I know this is kind of off topic but I was wondering if you
knew where I could find a captcha plugin for my comment form?
I'm using the same blog platform as yours and I'm having problems finding
one? Thanks a lot!

Чтобы lc работало с русскими буквами при локали utf8, добавить

if ( $ENV{LANG}=~ /utf/i ) { use Encode; Encode::_utf8_on($_) }

В результате получается монстр:

rename 'use locale;if($ENV{LANG}=~/utf/i){use Encode;Encode::_utf8_on($_)};tr/ /_/;$_=lc' *

Причём и это не полное решение: часть сообщения об ошибке в случае невозможности переименования будет крякозябрами :(

Есть идеи? И вообще, как обеспечить работу lc с русскими буквами без таких громоздких конструкций?

а просто use utf8;?
--
Signature invent in progress 24% ##........

hello!,I like your writing very so much! share we keep up a correspondence
extra approximately your article on AOL? I need a specialist on this area to resolve my problem.
Maybe that is you! Taking a look forward to look you.

Если список файлов берется из текстового файла (cat ./spisok.txt) и имена файлов содержат пробелы, то такая схема не будет работать

В таких случаях я поступаю так:

cat spisok.txt| while read lala;                                                0:56 07-08-04  pts/1
do
cp "$lala" "$lala".new
done

Seclorum

>Если список файлов берется из текстового файла (cat ./spisok.txt) и имена файлов содержат пробелы, то такая схема не будет работать

Какая именно? ;)

о! это тема! мне как раз нужно сконвертировать диск из koi8-r в utf8 в связи с переключением системной локали на последнюю...

Спасибо ramok за капитальный труд и mancubus за идею. Господа линуксоиды, добавляйте сюда свои способы переименовывания ;)

добавлю свои 2 копейки - пакет mmv (apt-get install mmv), включает в себя утилитки mmv, mcp, mad, mln (ну, все они линки на один exeшник, но це не столь важно ;)

Today, I went to the beach front with my children. I found a sea shell and gave it to my 4 year old
daughter and said "You can hear the ocean if you put this to your ear." She put
the shell to her ear and screamed. There was a hermit crab inside
and it pinched her ear. She never wants to go back! LoL
I know this is totally off topic but I had to tell someone!

I like the helpful information you provide to your articles.
I will bookmark your blog and check again here
regularly. I am relatively sure I'll be told plenty of new stuff proper right here!
Best of luck for the next!

I know this if off topic but I'm looking into starting my own blog and was wondering
what all is required to get set up? I'm assuming having a blog like yours would cost a pretty
penny? I'm not very web savvy so I'm not 100% certain. Any recommendations or
advice would be greatly appreciated. Many thanks

Вот еще один пример для переименовании, т.е. везде убирает префикс kinopoisk.ru- из имени файлов

$ find . -print0 -type f | xargs -0 rename -v 's/kinopoisk\.ru-//'

P.S.
у меня bash и даже с

$ shopt -s globstar

подобное

$ rename 's/kinopoisk\.ru-//' **/*

работает как то не так.

Отправить комментарий

Google Friend Connect (leave a quick comment)
loading...
Содержание этого поля является приватным и не предназначено к показу.