Perlスクリプトで文字列検索後に指定フィールドの値を変数へ

このQ&Aのポイント
  • Perlスクリプトで文字列を検索し、指定したフィールドの値を変数に入れる方法について教えてください。
  • 現在、grepやawkを使用して文字列を検索していますが、ファイル全体が検索対象になってしまい困っています。
  • 検索文字列は「2013/11/19,09:00:00,13:00:00」で、データはcsv形式で保存されています。
回答を見る
  • ベストアンサー

perl 文字列検索後に指定フィールドの値を変数へ

菊池と申します。 perlスクリプトで下記のような文字列を検索し、検索されたら指定したフィールドの値を変数に入れたいのですが、grepやawkを使うと、ファイル中のすべてが検索対象になってしまい困っております。 文字列検索の表現方法をご教授頂けると大変助かります。 下記へperlスクリプトの一部を記載させて頂きました、データはcsv形式です。 変数に入れる事が出来なかったので、抽出した値をファイルへ出力させています。 検索文字列=2013/11/19,09:00:00,13:00:00 データの中味 <94>N/<8c><8e>/<93>ú,<89>ð<90>Í<8a>J<8e>n<8e><9e><8d><8f>,<89>ð<90>Í<8f>I<97>¹<8e><9e><8d><8f>,<8c>ö<8b>¤<8d>À<95>WX(m),<8c>ö<8b>¤<8d>À<95>WY(m),<95>W<8d><82>H(m),<88>Ú<93>®<95>½<8b>Ï<92>lX(m),<88>Ú<93>®<95>½<8b>Ï<92>lY(m),<88>Ú<93>®<95>½<8b>Ï<92>lH(m),<8f><89><8a>ú<92>l<82>©<82>ç<82>Ì<95>Ï<93>®<97>ÊX(m),<8f><89><8a>ú<92>l<82>©<82>ç<82>Ì<95>Ï<93>®<97>ÊY(m),<8f><89><8a>ú<92>l<82>©<82>ç<82>Ì<95>Ï<93>®<97>ÊH(m),2D<8b><97><97>£(m),3D<8b><97><97>£(m),<88>Ú<93>®<95>½<8b>Ï2D<8b><97><97>£(m),<88>Ú<93>®<95>½<8b>Ï3D<8b><97><97>£(m),<91>ª<88>Ê<83>t<83><89><83>O,<91>ª<88>Ê<90>¸<93>x,<88>Ù<8f>í<92>l<83>t<83><89><83>O<81>i<8f><89><8a>ú<92>l<81>j,<88>Ù<8f>í<92>l<81>i<8c>x<89>ú<83><89><83><93><83>N<81>j,<94>ò<82>Ñ<92>l<83>t<83><89><83>O, 2013/11/18,01:00:00,05:00:00,-68213.2327,17746.2653,2093.7982,-9999.0000,-9999.0000,-9999.0000,5.0099,-0.5989,-4.8100,16215.1100,16255.8006,-9999.0000,-9999.0000,4,0.0019,0,0,0, 2013/11/18,05:00:00,09:00:00,-68213.2273,17746.2666,2093.7872,-9999.0000,-9999.0000,-9999.0000,5.0153,-0.5976,-4.8210,16215.1061,16255.7959,-9999.0000,-9999.0000,4,0.0014,0,0,0, 2013/11/18,09:00:00,13:00:00,-68213.2256,17746.2692,2093.7792,-9999.0000,-9999.0000,-9999.0000,5.0170,-0.5950,-4.8290,16215.1030,16255.7923,-9999.0000,-9999.0000,4,0.0016,0,0,0, 2013/11/18,13:00:00,17:00:00,-68213.2236,17746.2737,2093.7682,-9999.0000,-9999.0000,-9999.0000,5.0190,-0.5905,-4.8400,16215.0981,16255.7866,-9999.0000,-9999.0000,4,0.0014,0,0,0, 2013/11/18,17:00:00,21:00:00,-68213.2306,17746.2741,2093.7672,-9999.0000,-9999.0000,-9999.0000,5.0120,-0.5901,-4.8410,16215.1015,16255.7899,-9999.0000,-9999.0000,4,0.0016,0,0,0, 2013/11/18,21:00:00,01:00:00,-68213.2308,17746.2739,2093.7882,-9999.0000,-9999.0000,-9999.0000,5.0118,-0.5903,-4.8200,16215.1017,16255.7916,-9999.0000,-9999.0000,4,0.0016,0,0,0, 2013/11/19,01:00:00,05:00:00,-68213.2221,17746.2743,2093.8062,-9999.0000,-9999.0000,-9999.0000,5.0205,-0.5899,-4.8020,16215.0968,16255.7880,-9999.0000,-9999.0000,4,0.0017,0,0,0, 2013/11/19,05:00:00,09:00:00,-68213.2140,17746.2808,2093.7982,-9999.0000,-9999.0000,-9999.0000,5.0286,-0.5834,-4.8100,16215.0870,16255.7777,-9999.0000,-9999.0000,4,0.0013,0,0,0, 2013/11/19,09:00:00,13:00:00,-68218.2472,17746.8587,2098.6543,-9999.0000,-9999.0000,-9999.0000,-0.0046,-0.0055,0.0461,16217.2238,16258.2532,-9999.0000,-9999.0000,4,0.0017,0,0,1, 2013/11/19,13:00:00,17:00:00,-68218.2538,17746.8600,2098.6633,-9999.0000,-9999.0000,-9999.0000,-0.0112,-0.0042,0.0551,16217.2263,16258.2563,-9999.0000,-9999.0000,4,0.0014,0,0,1, 2013/11/19,17:00:00,21:00:00,-68218.2603,17746.8538,2098.6473,-9999.0000,-9999.0000,-9999.0000,-0.0177,-0.0104,0.0391,16217.2349,16258.2638,-9999.0000,-9999.0000,4,0.0016,0,0,1,   <<スクリプトの一部>> #`grep "'2013/11/19,09:00:00,13:00:00'" $SS | awk -F"," '{print \$13}' $SS > $SS-2D`; #`grep "'2013/11/19,09:00:00,13:00:00'" $SS | awk -F"," '{print \$14}' $SS > $SS-3D`; `awk -F"," '\$1 ~ \/2013\/11\/19\/ && \$2 == \/09\:00\:00\/ {print \$13}' $SS > $SS-2D`; `awk -F"," '\$1 ~ \/2013\/11\/19\/ && \$2 == \/09\:00\:00\/ {print \$14}' $SS > $SS-3D`; 以上 よろしくお願いいたします。

  • Perl
  • 回答数6
  • ありがとう数10

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

  • ベストアンサー
  • ybnormal
  • ベストアンサー率50% (220/437)
回答No.6

こういうことですか? while(<>){ chomp; @temp = split(/,/ $_); if(/2013\/11\/19,09:00:00,13:00:0/){ print "$temp[13]\n"; print "$temp[14]\n"; } }

nnirosan
質問者

お礼

ご教示頂いた通りで出来ました。 皆様に暖かいご教示を頂けた事、大変感謝しております。本当に助かりました、有難うございました。

その他の回答 (5)

  • ybnormal
  • ベストアンサー率50% (220/437)
回答No.5

まだしたいことがよくわかりません。 追加のコメントのとおりのことをするのであれば、あなたのgrepやawkを使ったやり方で問題ないように思えますが(最初のGrep+Awkはパイプの使い方がちょっと間違っていると思いますが)、それでは不都合があるということなので、具体的にAwkやGrepでは何が都合が悪いのか書いてもらえればもっと回答がつくと思います。

nnirosan
質問者

補足

端末上で、 grep '2013/11/19,09:00:00,13:00:00' 入力ファイ名 | awk -F"," '{print $13}'を実行すると 16217.2238が得られるます。 grep '2013/11/19,09:00:00,13:00:00' 入力ファイ名 | awk -F"," '{print $14}'を実行すると、 16258.2532が得られるます。 16217.2238と16258.2532の値が欲しいのです。 perlの中で、grepとawkの使い方が出来てないのです。 grepやawkの使い方と上記値を抽出出来るperlの表現方法がお解りでしたら、ご教示してくださるとと大変助かりますが。 たどたどしい、文章でもうしわけありません。 よろしくお願いいたします。 

  • ORUKA1951
  • ベストアンサー率45% (5062/11036)
回答No.4

 Perlは、多次元のデータを扱えますが、それが配列とハッシュ(連想配列)です。配列のハッシュとか、ハッシュの配列とか、ハッシュのハッシュとか・・  あなたの場合、先に示したように、配列のハッシュにデータをすべて入れて、その要素にアクセスする方法が最も楽です。  Perlを極めようとすると、"プログラミングPerl"は必携ですので、中古本でも良いので入手されたらいかがかと思います。  プログラミングPerl(第3版)Volue1 の 9章データ構造 9.1 配列の配列 9.2 配列のハッシュ 9.3 ハッシュの配列 9.4 ハッシュのハッシュ 9.5 関数のハッシュ 9.6 より複雑なレコード 9.7 データ構造を保存する  ですね。  No.2さんが言われているようにsplitで、データをひとつのデータテーブルに入れて、あとは自在にキーなり、何番目かを取り出して比較なり処理すれば良いです。

  • ORUKA1951
  • ベストアンサー率45% (5062/11036)
回答No.3

検索→変数 と言う意味がわかりません。 一行ごとに、配列のハッシュに代入して3次元のテーブルを作成した時点で、すでにひとつひとつのデータは変数として扱うことで出来ます。 @head = (<94>N/<8c><8e>/<93>ú,<89>ð<90>・・・【中略】・・・<9e>,・・) @keys = (2013/11/18-01:00:00-05:00:00,2013/11/18-05:00:00^09:00:00,・・・) $DATA{2013/11/18-01:00:00-05:00:00} = (-68213.2327,17746.2653,2093.7982,-9999.0000,-9999.0000,-9999.0000,5.0099,-0.5989,-4.8100,16215.1100,16255.8006,-9999.0000,-9999.0000,4,0.0019,0,0,0, 20) あとは、それぞれのデータにアクセスすればよい。

nnirosan
質問者

補足

支離滅裂な文面で申し訳有りません したい事は、2013/11/19,09:00:00,13:00:00<--左記の 文字列がデータファイル(csv形式)の中に記述されていたら、13列目と14列目の値を変数にセットしたいと言う事です。 上記文字列が記述されているのはデータファイルの中に1行しか有りません。 上記条件で得た、13列目と14列目の値と同じ列の値を比較して変動量を求めたいのです。 perlの超初心者です、perlはとても便利ですが、使いこなすまでに至っていません。 ご教授をよろしくお願いいたします。

  • ybnormal
  • ベストアンサー率50% (220/437)
回答No.2

特定のフィールドだけをパターンマッチの対象にしたいということですか? ならSplitで各フィールドをアレイに入れておいて、必要なアレイだけ比較対象にすればいいのでは。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

ん~.... 必要な要件が十分に書かれていない.... 「grepやawkを使うと、ファイル中のすべてが検索対象になってしまい困っております」ってあるけど ・なにがどう「困る」のか, さっぱりわからない. ・ファイル中の「検索対象の部分」と「検索対象でない部分」を区別する方法がどこにも書かれていない. ということで, とりあえずこれらを明確にしてください. あと, 「変数に入れる」ってどういうことでしょうか? 該当するものが複数あったら, どうしたらいいんでしょうか?

関連するQ&A

  • メールの文字化け

    Outlook2007 を使っているのですが、今回知人に送ったメールが 途中まではちゃんと読めるのですが、 途中から突然”Œg‘Ñ‚©‚ç“d˜b‚ð‚µ‚½‚̂́A‰Æ‚Ì“d˜b‚ÌŽq‹@‚ª‰ó‚ê‚Ä‚¢‚Đe‹@‚àƒR[ƒhƒŒƒX‚Å‚Í‚È‚¢‚Ì‚Å ”のように文字化けしてしまいました。 このような文字化けが起きた原因はなんでしょうか?

  • 行・列の整理! perl

    perlでデータを並び替えて整理したいです。 【元データ】 A a b A c d A e f A g h B i j B k l B m n C o p C q r C s t C u v ・ ・ ・ 上記のデータを下記のように並び替えしたいのですが上手くできずに困っています。 どのような記述をすれば良いのでしょうか。間の空白はタブ区切りです。 【目標】 A a b c d e f g h B i j k l m n C o p q r s t u v D ・ 現在、元データから A B C D ・ ・ というデータを作り、元データと比較していますが上手くいきません。 for($i=0; $i<@key; $i++){ print OUT "$key[$i]"; for($j=0; $j<@data; $j++){ if($key[$i] =~ /$data[$j]/){    #部分一致 print OUT "$'"; } } print OUT "\n"; } 部分一致の行を正規表現を用いて上手く処理したいのですがやり方がわからず躓いています。 宜しくお願いします。

    • ベストアンサー
    • Perl
  • 巨大なCSVの加工(指定列のみの抽出)について

    巨大なCSVの加工(指定列のみの抽出)について 下記のような構成のCSVファイルがあります。 "ID","a","b","c","d","e","f","g","h","i","j","k","l","m" "0001","a","b","c","d","e","f","g","h","i","j","k","l","m" "0003","a","b","c","d","e","f","g","h","i","j","k","l","m" "0004","a","b","c","d","e","f","g","h","i","j","k","l","m" ・ ・ ・ 例えば、 ここから"ID"列と"c"列と"f"列のみ抽出して新たなCSVファイルで保存。 という処理を行いたいのですが、行数が5000万行近くあり、ファイルサイズが80GB程あるので エクセルはおろかアクセスでも開くことができません。 テキストエディタの秀丸64bit版なら開くことができますが、指定列の抽出方法が分かりません。 秀丸のマクロでもVBSでも良く、また膨大な待ち時間がかかっても構わないので実現する方法について お知恵をお貸しください。

  • perlでcsvの指定フィールドに書き込みする方法

    perlを勉強中の初心者です。 以下のような入力ファイル(csv)があった場合、特定のフィールド(この場合"0")を参照して、その数字を元に、出力ファイルには、参照したフィールドからデータ書き込むプログラム方法を教えてください。 ---入力ファイル 0,a,b,c 1,d,e,f 2,g,h,i 10,w,s,x ---出力ファイル 0,a,b,c ,1,d,e,f ,,2,g,h,i ,,,,,,,,,,10,w,s,x

  • Perl テキスト内の文字列 合計値

    ご教示お願い致します。 test.txt --------------- a,a,a c,b,b b,c,b a,a,d a,e,e --------------- ↑のようなテキストがあり それを 1列目[0] a = 3 b = 1 c = 1 d = 0 e = 0 2列目[1] a = 2 b = 1 c = 1 d = 0 e = 1 3列目[2] a = 1 b = 2 c = 0 d = 1 e = 1 このように求めたいのと、 全ての配列から a = 6 b = 4 c = 2 d = 1 e = 2 という風に求めたいのですが、どのようにするのでしょうか?

  • awkの文法

    以下のawkの「'\'7b」の部分と「}'」の部分がmanを見てもどうしてもわかりません。 どなたか教えていただけないでしょうか? grep Cairns /etc/passwd | awk -F: '\'7b print $3 }'

  • EXL指定した文字列リストと同一を指定セルに表示

    下記のようなエクセルデータになっています。 表示の関数についてご教授願いますようお願いいたします。 上部の検索条件です(50行くらいあります) A列   B列   C列   D列   E列   F列 a     a     a     b     c 1     1    1     3     1 下部のフィールドです(数百行あります A列   B列   C列   D列   E列   F列 a     a     a     b     c 1     1    1     3     1 2     2    2     E     2 表示したい条件 A列   B列   C列   D列   E列   F列 a     a     a     b     c 1     1    1     3     1 2     2    2     E     2 F列のセルにD列と同じ文字列がある場合、文字列又は”○”で 表示出来たらと思います。 よろしくご教授のほどお願いいたします。

  • 複数の文字列を検索

    あるログファイルの文字列を取得して。検索でヒットした文字列行 を返すスクリプトを作成しております。 検索:"OK"    日付 対象行 : OK! Tue Jul 19 文字列"OK"は普通に # grep "OK" ログファイルPath で検索できますが、 文字列と日付を両方引っ掛ける場合は・・・ grep -e "OK" -e env LANG=c date -u +"%a %b $d" ログファイルPath 当然コマンドエラーになります。 dateコマンドから日付を取得して、grepにて引っ掛ける方法を知りたいので すが、お分かりになる方、ご教授お願い致します。

  • エクセル 検索した値の列の一番上をかえすには?

    4×5の表にアルファベットがランダムに重複なく入っている表で、指定したアルファベットのがどの列にあるか求めるにはどうしたら良いでしょうか。 列のタイトルを「あ、い、う、え、お」、 行のタイトルが「ア、イ、ウ、エ」の表で、例えばaがう-イのにあるときに、「う」という値を表示したいです。 A B C D E F 1 □ あ い う え お 2 ア m 3 イ k a … 例:検索値A→結果う よろしくお願いします。

  • エクセルで計算後の値で検索したい

    教えてください。 たとえば A1セルに1 B1セルに2 C1セルに=A1+B1という数式を入れたら3と表示されます D1に=VLOOKUP(C1,E1:F10,2,FALSE)としたらN/Aとなります E1は1、E2は2、E3は3、E4は4・・・・・・ F1は11、F2は12、F3は13、F4は14・・・・・ C1セルの3という値でE3の3を検索しF3の13を表示させることはできないでしょうか? アドバイスお願いします。

専門家に質問してみよう