コマンドライン引数で正規表現を指定する方法

このQ&Aのポイント
  • Perlのコマンドライン引数を使用して正規表現を指定する方法を紹介します。
  • コマンドライン引数から正規表現を読み込む際にエスケープが必要な場合の方法を解説します。
  • 具体的なコード例として、perl grep.plコマンドを使って正規表現を指定する手順を説明します。
回答を見る
  • ベストアンサー

コマンドライン引数で正規表現を指定したい

Perlでgrep -Aのようなことがしたいです。 ---------------grep.pl------------------------------- use strict; use warnings; #コマンドライン引数の確認 if(@ARGV != 3){ die "USAGE: \0 [num] [regex] [file]"; } #数字の読み込み my $num = $ARGV[0]; #正規表現の読み込み my $regex = qr/$ARGV[1]/; #ファイル名の読み込み my $file = $ARGV[2]; #該当行を保存する配列 my @lines = (); open my $fh, '<', "$file" or die "$!"; my @file = <$fh>; close $fh; for(my $i=0; $i<@file; $i++){ if($file[$i] =~ /$regex/){ push @lines, $file[$i]; for(my $j=1; $j<=$num; $j++){ if($i+$j < @file){ if($file[$i+$j] !~ /$regex/){ push @lines, $file[$i+$j]; }else{ last; } }else{ last; } } } } foreach my $item (@lines){ print $item; } ------------------------------------------------- ところが、正規表現がうまく読み込めません。 perl grep.pl 2 \d{4}\/\d{2}\d{2} test.txt などとしても、\d{4}\/\d{2}\d{2}の部分が機能しません。 コマンドライン引数から正規表現を指定するにはどうしたらよいでしょうか。

  • koun
  • お礼率37% (81/216)
  • Perl
  • 回答数1
  • ありがとう数13

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

perlに引数を渡すまえに、shellがエスケープ処理を展開してしまいます。 なので、コマンドラインでは、それを抑止するために、 ' ' で囲む必要があります。 perl grep.pl 2 '\d{4}\/\d{2}\d{2}' test.txt

koun
質問者

お礼

ありがとうございます。できました。shellについてもっと知りたいです。

関連するQ&A

  • コマンドライン引数

    コマンドライン引数で以下のようなプログラムを実行したいのですが どうしたらいいのか分かりません!! みなさんの意見を聞かせてください(lll´Д`lll)    □☆□□□☆□□□☆□□□☆□    ☆★☆☆☆★☆☆☆★☆☆☆★☆    □☆□□□☆□□□☆□□□☆□    □☆□□□☆□□□☆□□□☆□    ☆★☆☆☆★☆☆☆★☆☆☆★☆    □☆□□□☆□□□☆□□□☆□    □☆□□□☆□□□☆□□□☆□    ☆★☆☆☆★☆☆☆★☆☆☆★☆    □☆□□□☆□□□☆□□□☆□    □☆□□□☆□□□☆□□□☆□ プログラムは途中まで作ったのですが、肝心なとこは 全く分りませんっっ #include <stdio.h> int main(int argc, char *argv[]) { int yoko, tate, i, j; if( argc < 3 ) return(1); sscanf( argv[1], "%d", &yoko ); sscanf( argv[2], "%d", &tate ); for( j = 0; j < tate; j++ ) { printf("\n"); } return(0); } /* end of pat2.c */

  • 正規表現が解読できません。

    ツールが対象ファイルを認識する規則が正規表現で記載されているのですが、 正規表現について無知なため、解読することができずに困っております。 ネット等で検索し、[A-Z0-9]や{4,4}など部分的には解読することができたのですが・・・ FILE_COPY.REGEX1=<ABC>\t.+\\\\ABC(\\\\.*)?\\\\[A-Z0-9]{4,4}[0-9]{3,3}[A-Z0-9]+\\\\[A-Z0-9]{4,4}[0-9]{3,3}[A-Z0-9]+\\.gz FILE_COPY.REGEX2=<DEF>\t.*\\\\[^\\\\]*(?<\!\\.tar) FILE_COPY.REGEX3=<GHI>\t.+\\.xml\\.gz どなたかお時間のある方がいらっしゃいましたら、ご教示いただけないでしょうか。 どうぞよろしくお願いいたします。

  • ruby 正規表現について教えてください。

    aというテキストファイルを読み込むときの処理なんですが、 aというテキストファイルは↓のようになってます。 #AA1#(001-1 001-2 001-3) #AA2#(pro pro) #AA3#(num1) #AA1#(002-1 002-2 002-3) #AA2#(dro dro) #AA3#(num2) このファイルから#AA1#の()でくくった部分を縦に並べて、その横に#AA3#の()でくくった部分を縦で表示させたいんです。 実行結果を下のようにしたいです。 001-1 num1 001-2 num1 001-3 num1 002-1 num2 002-2 num2 002-3 num2 一応がんばって、下のように考えたんですが、上手く実行できないです。どうか、回答おねがいします。 a= [] b = [] c = [] while line = gets if /#AA1#\((.*\s)(.*\s)(.*)\)/ =~ line a.push $1 a.push $2 a.push $3 end if/#AA3#\((.*)\)/ =~ line b.push $1 end end c = [a,b] puts c

  • 正規表現 誤入力にもマッチ

    単語検索のスクリプトで利用者がミスタイプしたときにもマッチするようにしたいと考えています。 例えば、1文字間違って入力した場合にもマッチするように以下のようなスクリプトを書いたのですが、もっと簡単な記述が(標準以外のモジュールを使わずに)できないでしょうか?ご教示いただけましたら嬉しいです。 以下のスクリプトでしていること・・・ hello を .ello|h.llo|he.lo|hel.o|hell. に変換してマッチ。 use strict; my $data = "hallo"; my $query = "hello"; my $q_len = length $query; my $query1 = $query; my @queries; for (my $i=0;$i<$q_len;$i++){ substr($query1, $i,1,"."); push @queries, $query1; $query1=$query; } my $regex = join ("|", @queries); if ($data=~/$regex/){ print "matched\n"; }else{ print "no match\n"; }

    • ベストアンサー
    • Perl
  • 【PHP】関数から渡した引数を正規表現で扱うには?

    下記(1)はディレクトリ「sample_dir」のファイル一覧を取得し、ファイル名「hogehoge」から始まるものだけを一覧表示させたものです。 「hogehoge」以外の文言でも絞り込めるように関数を呼び出して((2))、指定文言を引数で$xに渡したいのですが、引数が認識されません。 引数を正規表現で扱うには、どのように記述したら良いですか。 ご教示をお願いします。 ---------------------------------------- (1) ---------------------------------------- //対象ディレクトリ $dir_s="./sample_dir"; //ディレクトリ内のファイルを取り出す $filelist=scandir($dir_s); //ファイル数をチェック $count=count($filelist); for($i=0; $i<$count; $i++){ $y = ($filelist[$i]); if(preg_match("/^hogehoge/", $y)){ print_r($y); } } ---------------------------------------- (2) ---------------------------------------- function file_search($x){ for($i=0; $i<$count; $i++){ $y = ($filelist[$i]); if($z = preg_match($x, $y)){ print_r($y); } } } file_search("/^filename/"); //引数「filename」でマッチさせたい

    • ベストアンサー
    • PHP
  • 正規表現の使い方

    正規表現の使い方で困っています。 lsでディレクトリの中身を確認して、その名前とひっとするものがあれば、IFの中に入りたいのですが、エラーが出てしまいます。 正しい書き方をご存じのかたご回答のほど宜しくお願いします。 set `cat /DS/tmp/liste.fal |grep -v \#` for i do verz=$(dirname $i) set `ls $verz` for j do if (test $j = "Kommentar.txt") then echo "$j ist jetzt Kommentar.txt" echo "cp $j $zielverz" elif [[ "$j" =~ "*fal" ]] then echo "$j ist jetzt *.fal" echo "cp $j $zielverz" と続いていくのですが、[[ "$j" =~ "*fal" ]] この部分が間違っているようです。 シンタックエラーがでます。 私が検索したいファイル名はのようなかたちです。 riipe.fal フォルダの中には、他にも rippe.fal.neu rippe.erg.fal.neu Kommentar.txt という名前のものがあります。 宜しくお願いします。

  • perl-cgiのリネームについて

    Perl-CGIで ABCという、ディレクトリの中のファイルの名前を、ランダムな名前に変換したいのですがうまくいきません。 これを動作させるたびになぜか、どんどんファイルが減っていってしまいます。 どなたか、教えていただけないでしょうか? 宜しくお願い致します。 #!/usr/local/bin/perl print "Content-Type: text/plain\n\n"; $| = 1; my ($sec,$min,$hour,$mday,$mon,$year,$wno) = localtime(time); my ($nowtime) = sprintf("%02d_%02d_%02d_%02d_%02d_",$year+1900,$mon+1,$mday,$hour,$min,$sec); #ディレクトリのファイル個数を記録する $dir = "./ABC/"; # ← ディレクトリを変数にセットする opendir DIR, $dir; @files = grep { !m/^(\.|\.\.)$/g } readdir DIR; # ← 「.」 「..」 以外のファイルを取得 close DIR; srand; for (my $i = @files; --$i; ) { my $j = int rand ($i + 1); next if $i == $j; @files[$i, $j] = @files[$j, $i]; } $num = 0; use File::Copy; foreach(@files){ $getpath = "$dir"."$_"; if( copy($getpath, "$dir".$nowtime.$num++.'.dat') eq 1){ $num++; unlink($getpath);}else{print "Copy Error"; exit;} }

    • ベストアンサー
    • CGI
  • コマンドラインによるファイル名指定

    #include<stdio.h> #include<stdlib.h> int main(int argc,char *argv[]) { FILE *fp,*fpc; int i=0; char line[1000]; fp = fopen("test.txt","r"); if(fp == NULL) { printf("File not found.\n"); exit(1);  }  fpc = fopen(argv[1],"w"); if(fpc==NULL){ fprintf(stdout,"Can not open file.\n"); exit(1); } while(fgets(line[i],1000,fp)!=NULL){ i++; } for(i=3;i<0;i--){ fprintf(fpc,"%s",line[i]); } fclose(fp); fclose(fpc); return 0; } コマンドラインでファイル名を指定し、そのファイルに、test.txt(4行の文字列)の内容を各行を逆順に書き出すプログラムですが、上手くいきません。ご指摘を願いします。

  • 「コマンドライン引数チェック」て何

    #include <stdio.h> int main(int argc, char *argv[]) { FILE *fp; char gyou[1024]; int gyousuu = 0; if ( argc < 2 ){ printf("file mei ga nai\n"); return -1; } fp = fopen(argv[1], "r"); if ( fp == NULL ){ printf("fopen dekinai\n"); return -2; } while(fgets(gyou, sizeof(gyou), fp) != NULL){ gyousuu++; } fclose(fp); printf("gyousuu=%d\n", gyousuu); return 0; }    以上のプログラムはご覧のとおり、「ファイルの行数を計算」のプログラムです。 さて以上の  if ( argc < 2 ){ printf("file mei ga nai\n"); return -1; } は「コマンドライン引数チェック」を行っています。・・・  if ( argc < 2 ){の「argcは2以上である必要がある」と参考書に書いてあります。   以上ですが意味が日光手前ですが、プログラムの行数をカウントするうえで、  「コマンドライン引数チェック」とはどんな作業を行っているとこなのでしょうか!?  よろしくお願いします。  

  • 【C言語】コマンドライン引数の標準入出力

    【C言語】コマンドライン引数の標準入出力 コマンドライン引数で、ファイル名を3つ渡します。-aの次のコマンドライン引数が、出力ファイル名です。 <<例>> ・実行モジュール -a 出力ファイル名 -b ファイル名 -c ファイル名 ・実行モジュール -c ファイル名 -a 出力ファイル名 -b ファイル名 もし出力ファイルが指定されなかった場合に、標準入出力を使いたいのですが、どうしたらいいかわかりません。 下記がソースの一部です。これをどう改造したらよいでしょうか。 分かる方いらっしゃいましたらご回答いただけると幸いです。 宜しくお願いします。 //出力ファイルを取得、書き込みモードでオープン for(j=1;j<argc-1;j++){ if(strcmp(argv[j],"-o")==0){ if((fo = fopen(argv[j+1],"w"))==NULL){ printf("open error!!\n"); exit(1); } } } while(fgets(buf,sizeof(buf),fp)!= NULL){ if(strstr(buf,"keyword")!= NULL){ //出力ファイルに出力 fprintf(fo,"%d:%s",line,buf); } }

専門家に質問してみよう