4

私はこのPerlワンライナーをテスト/試行していて、ファイルに何が起こったのかを理解しようとしています。ファイルが表示されなくなりました。それらを削除しましたか、それとも何が問題でしたか?

リストされているファイル名の例(元の):

IMG_0178.JPG
IMG_0182.JPG
IMG_0183.JPG
IMG_0184.JPG
IMG_0186.JPG

ファイル拡張子を小文字(.jpg)に変更したかっただけです。

perl -e'while(<*.JPG>) { s/JPG$/jpg/; rename <*.jpg>, $_ }'
4

2 に答える 2

9

renameグロブと一緒に使用しないでください。スカラーを使用します。置換する前にファイル名を新しい変数に割り当て、次のように古い名前の名前を変更した名前に変更してみてください。

perl -e'while(<*.JPG>) { ($new = $_) =~ s/JPG$/jpg/; rename $_, $new }'

で出力を確認してくださいls -1

IMG_0178.jpg                                                                                                     
IMG_0182.jpg                                                                                                
IMG_0183.jpg                                                                                              
IMG_0184.jpg                                                                                               
IMG_0186.jpg
于 2012-07-06T20:54:03.943 に答える
4

奇妙なことに、あなたのコードはあなたが望むことをするはずです。

スカラーコンテキストのようなファイルグロブ<*.JPG>は、パターンに一致する次のファイルを返します。両方ともスカラーコンテキストwhilerename適用するため、2つのグロブは各反復で同じ値を返します。

while (<*.JPG>) {
    s/JPG$/jpg/;
    rename <*.jpg>, $_;
}

ループの最初の反復では、によって$_設定さIMG_0178.JPGwhile、置換によってファイルタイプが小文字に設定されます。

次に、名前変更<*.jpg>がスカラーコンテキストで実行され、IMG_0178.JPGWindowsファイル名では大文字と小文字が区別されないため、同じリストの最初のファイルが返されます。

したがって、最終的に名前変更は必要に応じて実行rename 'IMG_0178.JPG', 'IMG_0178.jpg'されます。

このように書き直すrenameと、これがはっきりとわかります

sub ren($$) {
  print "$_[0] -> $_[1]\n";
}

while (my $file = <*.JPG>) {
  $file =~ s/JPG$/jpg/;
  ren <*.JPG>, $file;
}

出力

IMG_0178.JPG -> IMG_0178.jpg
IMG_0182.JPG -> IMG_0182.jpg
IMG_0183.JPG -> IMG_0183.jpg
IMG_0184.JPG -> IMG_0184.jpg
IMG_0186.JPG -> IMG_0186.jpg

幸運なことに、ファイルの名前は必要に応じて変更する必要があります。

しかし、これをしないでください。特に、重要な操作の代わりにprintステートメントを使用してプログラムを実行し、何が起こるかを確認できるようにする必要があります。

idが意図したことをより明確に行うので、これはより良いでしょう

perl -e '($f = $_) =~ s/JPG$/jpg/i and rename $_, $f while <*.JPG>'
于 2012-07-06T21:36:31.050 に答える