среда, 30 марта 2011 г.

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

ногда нужно производить массовые переименования файлов. Изучая командную строку юникса когда то, меня удивило отсутствие такой приятной возможности в 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


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

#!/usr/bin/perl

@ARGV || die " Usage:
scriptname файл1 файл2 ...
scriptname \"имя файла\" ...
scriptname имя\\ файла ...
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');
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;
}

Комментариев нет:

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