- ベストアンサー
以下のperlのプログラムについて
以下は、多くのファイルの名前を一度に変更するための プログラムのはずなのですが・・・(参考書からもってきました) 分からないところがあるので教えて下さい。 #! /usr/bin/perl/ $op = shift or die"Usage: rename expr [files]\n"; chomp(@ARGV = <STDIN>) unless @ARGV; for(@ARGV){ $was = $_; eval $op; die $@ if $@; rename($was,$_) unless $was eq $_; } 1. opは何ですか? 2. Usageは何ですか? 3. exprは何ですか? 4. ARGVは何ですか? 5. wasは何ですか? 6. $_は何ですか? 7. eqは何ですか? 8. ファイルはどこのディレクトリに入っているものか 宣言しなくていいのですか? 9. できれば、プログラムの一行ずつ教えて頂けると助かります。 perlの初心者、というよりパソコンを使う事自体が 初心者でわからないことが多く困っています。 参考書でいろいろ調べましたが、まだ分からなくて・・・ 勉強不足で申し訳ありませんが宜しくお願い致します。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
初心者向きのプログラムじゃないですね、これ。 Perl には「暗黙の了解」的なお約束事項が多いのですが、それを使いまくってます。 勉強したいのであれば、ちゃんとした本を買って、もう少し素直なプログラムを見て勉強した方がいいと思います。 1: #! /usr/bin/perl/ 2: 3: $op = shift or die"Usage: rename expr [files]\n"; 4: chomp(@ARGV = <STDIN>) unless @ARGV; 5: for(@ARGV){ 6: $was = $_; 7: eval $op; 8: die $@ if $@; 9: rename($was,$_) unless $was eq $_; 10:} >1. opは何ですか? 変数の名前です。 $ が先頭についている文字列は変数として扱われます。 >2. Usageは何ですか? "" で囲まれた文字列は、そのまま文字列として扱われます。 ただし、$文字列(変数) が入っている場合、変数が展開されます。 例えば、 $exp = "ほげ"; print "hogehoge$exp"; とすると、hogehogeほげが印字されるはずです。 >3. exprは何ですか? 評価: express の意味で、後に続く文字列をperl の命令として実行します。 ここでは、3行目で$op の中に設定した1番目の引数を実行します。 ファイル名の変更に使用しているのだと思います。 例えば、s/.bat/.sh/g であれば、$_ に設定された文字列のうち .bat を含んでいる場合、.bat を .sh に置き換えるという意味になります。 >4. ARGVは何ですか? プログラムを実行する際に使用された引数が中に入っている変数です。 $ rename expr hoge.txt hoge2.txt hoge3.txt のように起動した場合、 $ARGV[0] = expr $ARGV[1] = hoge.txt $ARGV[2] = hoge2.txt $ARGV[3] = hoge3.txt になります。 ただし、このプログラムでは 3 行目でshift を使用しているので、それ以降は $op = expr $ARGV[0] = hoge.txt $ARGV[1] = hoge2.txt $ARGV[2] = hoge3.txt のようにになります。 >5. wasは何ですか? $was は、変更前のファイル名だと思います。 ひとつ前の変数 >6. $_は何ですか? 暗黙の変数です。 for(配列) や、 foreach(配列) を使用した場合に、配列の中身がひとつずつ 入ってくることになっている変数です。 なので、この場合は、 $ARGV[0], $ARGV[1], $ARGV[2] の順番で値が設定されているはずです。 >7. eqは何ですか? 文字列として比較を行う演算子です。 "0001" == "1" は真、"0001" eq "1" は偽になります。 >8. ファイルはどこのディレクトリに入っているものか宣言しなくていいのですか? 単純にrename しているだけなので、このままだとこのプログラムを実行しているカレントディレクトリ上のファイルが使用されます。 指定する場合は、個々のファイル名を絶対パスで指定する必要があるでしょう。 >9. できれば、プログラムの一行ずつ教えて頂けると助かります。 1: #! /usr/bin/perl/ perl プログラム名のように指定せず、 プログラム名だけでコマンドを実行させるための マジックナンバー。 3: $op = shift or die"Usage: rename expr [files]\n"; $op にプログラムに指定された最初の引数を代入して、引数変数@ARGV の先頭を削除。 もしこれが失敗したら(例えば、引数がなかった場合など) Usage: rename expr [files](改行) を表示して終了する。 4: chomp(@ARGV = <STDIN>) unless @ARGV; もし、先頭を削除されたために@ARGV の中身がなくなったら(== もともと引数が1つしかなかった場合)、標準入力(通常はキーボード、リダイレクトしてる場合はそのリダイレクト元)からファイル名のリストを読み込む。 5: for(@ARGV){ ファイル名リストの数分だけ、ひとつひとつ処理を行う 6: $was = $_; 変更前のファイル名として、$was を覚えておく 7: eval $op; $op を実行して、変更後の名前を生成する。 例えば、$was = $_ = hoge.txt 、 $op = s/txt/sjis/ だった場合、 $_ は、 hoge.sjis に書き換えられる 8: die $@ if $@; もし実行結果が失敗だったら、そのエラーメッセージを表示して終了する。 $@ はエラーメッセージが設定される変数。 9: rename($was,$_) unless $was eq $_; 変更前後のファイル名が違っている場合だけ、変更前、後の名前を指定してファイル名の変更を行う。 10:} 5行めからのループ終了。
その他の回答 (2)
- tailkuppa
- ベストアンサー率53% (52/98)
#1 です。 expr とeval を勘違いしてたので訂正します。 expr は、文字列の中の文字なので、確かにプログラム実行には関係ありません。 regular EXPRession (正規表現)の略だと思います。 正規表現については、このスペースで説明できるような概念ではないので詳しくは 説明しませんが、特定の文字列を指し示すために使用する表現方法のことです。 ここでは複数のファイル名の共通部分を抜き出して置き換えるために使用しています。 http://www.google.co.jp/ あたりで、正規表現 で検索してみると,どんなものか見当がつくと思います. s/変換前(正規表現)/変換後/ で変換前の正規表現にマッチする最初の文字を変換後の文字列に置き換えます. s/変換前(正規表現)/変換後/g にすると,変換前の正規表現にマッチするすべての文字を変換後の文字列に置き換えます. この辺りはPerl の本領発揮な部分なので,Perl の参考書なら必ず載っているはずです.
お礼
有難うございました。 あと、”教えて”の回答の探し方が分からなく、勘違いして 同じ質問をしてしまいました。そっちの質問は無視して下さい。
- haporun
- ベストアンサー率40% (230/562)
(1) shiftは対象配列の先頭要素を取り除いて返す関数です。 対象配列を指定しないときは、@ARGVが対象になります。 ここでは@ARGVの最初の要素を取り除いて返します。 もし、それができなければ、エラーメッセージを表示します。 (2)(3) Usage: 使い方。 exprは何の略だろ。 っていうか、文字列の中のものなので、プログラムと直接関係ないです。 (4) @ARGVでコマンドラインで入力された文字列が入ってきます。 たとえば、UNIXで ls /usr と入力した場合は、$ARGV[0]に '/usr' という文字列が入ってきます。 さらに多くの引数を入れた場合は、$ARGV[1]以降に入ってくるわけです。 (5) $とアルファベットで変数を表しています。 (6) $_これを、パソコン初心者と名乗るあなたに説明するすべはないような・・・。 for(@ARGV)とかくと、@ARGVのそれぞれの要素に対しての操作が可能になります。 そのとき、それの要素を表すのが$_です。 分かりませんね、次行きます。 (7) eqというのは文字列が同じかどうかを調べるための演算子です。 $a eq $bと書いたら、$aと$bが同じ文字列なら1を、違うなら''(空文字列)を返します。 (8) このスクリプトを呼び出すときに、引数として指定するのです。 (9) え? まぢで? 出直してきます(ぉ。
お礼
有難うございました。 これからも質問させて頂くので宜しくお願い致します。 あと、”教えて”の回答の探し方が分からなく、勘違いして 同じ質問をしてしまいました。そっちの質問は無視して下さい。 もっと勉強してきます!
お礼
有難うございました。 こんなに詳しく教えて頂けるとは!! 助かりました。これからはもっと頑張ります。 あと、”教えて”の回答の探し方が分からなく、勘違いして 同じ質問をしてしまいました。そっちの質問は無視して下さい。 早くパソコンに慣れなくては・・・