2009-12-02 2 views
5

У меня есть много файлов, которые я пытаюсь переименовать, я пытался сделать регулярное выражение, чтобы соответствовать им, но даже то, что я застрял на файлы названы как:Как я могу просто переименовать файлы с помощью Perl?

Имя файла 01

Имя файла 100

Имя файла 02

Имя файла 03

и т.д., я хотел бы к д.д. "0" (ноль), за какой-либо из файла, который меньше, чем 100, как это:

Имя файла 001

Имя файла 100

Имя файла 002

файла Имя 003

Ближайший я добрался до их совпадения с использованием этого find -type d | sort -r | grep '[1-9] [0-9] $', однако я не мог понять, как их заменить. Заранее благодарим за любую помощь, которую вы можете мне предложить. Im on CentOS, если это поможет, все это делается через SSH.

+0

ли ваши имена файлов на самом деле содержат пробелы? –

+0

Да, они выглядят так: «Имя файла 01» «Имя файла 101» –

+1

Можете ли вы рассказать о «инструментах», доступных на машине? У вас есть Perl, Python, Ruby или аналогичные установлены? –

ответ

12
perl -e 'foreach $f (glob("File\\ Name*")) { $nf = $f; $nf =~ s/(\d+)$/sprintf("%03d",$1)/e; print `mv \"$f\" \"$nf\"`;}' 

Немного перебор, может быть, но он делает то, что задают.

9
find . -type d -print0 | xargs -0 rename 's/(\d+)/sprintf "%03d", $1/e' 

или что-то подобное, при условии

  1. Вы GNU найти и GNU xargs (для -print0 и -0)
  2. у вас есть 'переименовать' утилита, которая поставляется с Perl
  3. Там в только одна группа цифр в имени файла. Если их больше одного, вам нужно что-то сделать с регулярным выражением, чтобы оно соответствовало числу, которое вы хотите переформатировать.
+0

Это близко к чему-то, что я собираюсь предложить, используя sed вместо xargs, поэтому я сделаю +1. – shoover

+0

Я знал, что xargs - это путь, я просто не мог написать точную команду. –

+0

+1 Для перечисления зависимостей (это, возможно, утилита переименования, на которую вы ссылаетесь, является одной yum или apt-get away). – ChristopheD

2

Выполнить две команды, в следующем порядке:

$ rename 's/File Name (\d)$/File Name 0$1/' * 
$ rename 's/File Name (\d\d)$/File Name 0$1/' * 

Сначала один переименовывает все меньше, чем 10, и присоединяет нуль. Второй переименовывает все меньше 100 и добавляет ноль. Результат должен быть трехзначным для всех имен файлов.

+0

В какой среде эти допустимые команды? –

+0

'rename' - это утилита, которая поставляется со стандартным распределением perl. Я запускал их под Linux Bash. –

+0

[Предполагается, что $ представляет командную строку.] –

0

вы можете что-то сделать с помощью perl или ruby.

поместить все эти файлы в том же каталоге

dirlisting = DIR.entries('.') 

dirListing.each do |file| 
num = file.match(/\d+$/).to_i 
if num < 100 
    find the position where start the number, with index and inject the 0 there. 
end 
end 
+0

Возможно, вы должны указать, что этот код является рубином, а не perl –

+0

, если вы прочитали мое предложение, вы увидите «perl ИЛИ ruby» –

+0

И вот почему я сказал, что вы должны устранить факт, что код является рубином. –

4

Является ли это одноразовая вещь? Если да, я собираюсь предложить что-то, что может показаться мною программистом здесь:

Проведите вывод вашей команды (find -type d | sort -r | grep ' [1-9][0-9]$') в файл и используйте редактор вместе с некоторыми глобальными поисковыми/заменами чтобы создать скрипт, который выполняет переименование.

Затем выбросьте скрипт.

Есть немного суеты и мало шансов, что вы в конце концов стреляете в ногу, пытаясь попытаться искусить (но неадекватно отлаженный) один лайнер, уйти в сорняки на ваши файлы.

+0

++! Иногда лучше использовать кудд, который вы понимаете, чем изучать «глубокую магию». – daotoad

+0

+1 Я думаю, что такого рода вещи часто являются наиболее прагматичным решением для одних требований. –

+0

Это может быть отказ, но это безопасная копия ... kudos. –

0
use strict; 
use File::Copy; 

my @files = glob 'File*Name*'; 

foreach my $filename (@files) { 
    if ($filename =~ m`^.*File.*Name.*?(\d+)`) { 
     my $number = $1; 
     next if ($number > 99); 
     rename $filename, sprintf("FileName%03d",$number); 
    } 
} 
+0

То, что переименовывает 'имя файла 100' в' имя файла 0100', который не предназначен. –

+0

Вы были, безусловно, правы. Добавлен код, чтобы сделать так, чтобы этого не произошло. –

1

В моем debian он хорошо работает с переименованием, протестированным с 300 файлами.

perl -e 'map `touch door$_.txt`, 1..300;' 
rename 's/(\d+)\.txt/sprintf("%03d.txt", $1)/e' *.txt 
0

если ваш пульт имеет Баш оболочку

for i in File*; 
do 
    case "${i##* }" in [0-9][0-9]) 
     echo mv "$i" "${i% *} $(printf "%03d" ${i##* })" ;; 
    esac; 
done 

удалить «эхо», чтобы сделать фактическое переименование