Perl-скрипт, который работал на Snow Leopard, больше не работает на Lion - PullRequest
1 голос
/ 08 ноября 2011

Раньше я брал произвольный набор файлов на рабочий стол в формате:

Снимок экрана 2011-11-08 в 8.10.23 AM.png

ЭкранСнимок 2011-11-08 в 8.08.57 AM.png

Запустите на них скрипт Perl и переименуйте их в

SS-2011-11-08 в 8.10.23 AM.png

SS-2011-11-08 в 8.08.57 AM.png

Это перестало работать, и переименование не происходит.Теперь, когда мне нужно изменить его, я бы хотел изменить его на:

ss-2011.11.08.at.8.10.23.AM.png

ss-2011.11.08.at.8.08.57.AM.png

  • заменить «Снимок экрана», так как в этом случае всегда нужно «ss»
  • заменить все - на .
  • заменить все пробелы на .

Я знаю, что это связано с жадностью, но я не писал это, и сколько бы я ни занимался, я могуКажется, не заставить его работать.Я использовал Perl всего несколько часов в моей жизни.Я думаю, что я мог бы сделать это в php в несколько строк, но хотел бы узнать, как сохранить его в perl, потому что всегда хорошо иметь возможность отлаживать.Я посмотрел правила форматирования regs, и они не применяются.Либо в Mac OS X Lion что-то пошло не так, либо Snow Leopard позволил тому, что не должно происходить.

Спасибо вам всем!

Вот что у меня есть:

 #!/usr/bin/perl -w

 chdir( "/Users/me/Desktop" ) or die;
 my @files = ();
 print "after my \@files array\n";
 print @files;

 while ( <*> ) {
    push @files, $_ if m!^Screen Shot (.*) at (.*)\.png!;
 }


 foreach my $f ( @files ) {
    my $new = $f;
    $new =~ s!^SS (.*) at (.*)\.png!ss-$1\_$2.png!;
    print "$f -> $new\n";
    rename ( $f, $new ) or die;
 }

Ответы [ 4 ]

1 голос
/ 08 ноября 2011

Просто замените замену на этот

$new =~ s/Screen\.Shot\.(.*)\.at\.(.*)/ss-$1.at.$2/;

и добавьте еще замены перед it:

$new =~ s/[- ]/./g;  # Replace all dashes and spaces to dots
0 голосов
/ 08 ноября 2011

Я использую Snow Leopard, и мои снимки экрана сохраняются как Screen shot ... (обратите внимание на строчные буквы s на shot). Лев теперь использует прописные буквы S? Если это так, и ваш оригинальный скрипт использовал строчную букву s, то это, вероятно, и сломало его. В любом случае, давайте это исправим.

Ваша замена

$new =~ s!^SS (.*) at (.*)\.png!ss-$1\_$2.png!;

ищет имена файлов, начинающиеся с SS, за которыми следует пробел, но звучит так, как будто вы хотите изменить имена файлов, начиная с SS, за которыми следуют -, или Screen [Ss]hot с последующим пробелом.

Кроме того, как указал @FailedDev, ваш цикл while добавляет только файлы, которые соответствуют ^Screen Shot (.*) at (.*)\.png, в ваш массив @files, поэтому вы foreach цикл никогда не увидите файлы, начинающиеся с SS.

Замените ваш код следующим:

#!/usr/bin/perl -w
use strict; # ALWAYS!

chdir( "/Users/me/Desktop" ) or die("Could not chdir() to ~/Desktop: $!");
foreach my $f (<*>) {
    my $new = $f;
    if ($new =~ s!^(?:SS-|Screen [Ss]hot )([\d-]+) at ([\d\.]+) ([AP]M)\.png!ss-$1.at.$2.$3.png!) {
        $new =~ s/\-/\./g;
        print "$f -> $new\n";
        rename ( $f, $new ) or die("Could not rename $f to $new: $!");
    }
}

Чтобы помочь вам понять, что происходит:

  • ^ после s! означает, что нужно смотреть только начало текста для замены, в данном случае имя файла
  • | между SS- и Screen [Ss]hot [сгруппированы по (?:)] означает, что нужно искать SS- или Screen [Ss]hot.
  • Три группы захвата [окруженные () без ?:] не содержат пробелов, поэтому $1, $2 и $3 в вашей замене не будут содержать пробелов .
  • Оператор if гарантирует, что код внутри блока if выполняется только в том случае, если имя файла совпадает, и подстановка действительно происходит.
0 голосов
/ 08 ноября 2011

Первое выражение (в if)

m!^Screen Shot \d+-\d+-\d+ at \d+\.\d+\.\d+\s[AP]M\.png$!

Второе выражение (хотя я бы подумал, что это технически избыточно, потому что выражение совпадения одинаково для групп захвата) будет:

s!^Screen Shot (\d+)-(\d+)-(\d+) at (\d+)\.(\d+)\.(\d+)\s([AP]M)\.png$!ss-$1.$2.$3.at.$4.$5.$6.$7.png!

у меня работает, по крайней мере!

Если вы хотите, чтобы я сломал это для вас, просто спросите!

0 голосов
/ 08 ноября 2011

Пока вы добавляете в массив все файлы, соответствующие приведенному ниже регулярному выражению:

/^Screen Shot (.*) at (.*)\.png/

Затем вы пытаетесь заменить каждый файл из вышеупомянутого массива, который выглядит так:

/^SS (.*) at (.*)\.png/

Как вы можете ожидать, что это сработает?

...