菊池と申します。
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`;
以上 よろしくお願いいたします。

A 回答 (6件)

こういうことですか?



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

}
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/02/22 22:18

まだしたいことがよくわかりません。


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

この回答への補足

端末上で、
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の表現方法がお解りでしたら、ご教示してくださるとと大変助かりますが。
たどたどしい、文章でもうしわけありません。
よろしくお願いいたします。 

補足日時:2014/02/22 17:24
    • good
    • 0

 Perlは、多次元のデータを扱えますが、それが配列とハッシュ(連想配列)です。

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

検索→変数


と言う意味がわかりません。
一行ごとに、配列のハッシュに代入して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)
あとは、それぞれのデータにアクセスすればよい。

この回答への補足

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

補足日時:2014/02/21 17:23
    • good
    • 0

特定のフィールドだけをパターンマッチの対象にしたいということですか?


ならSplitで各フィールドをアレイに入れておいて、必要なアレイだけ比較対象にすればいいのでは。
    • good
    • 0

ん~.... 必要な要件が十分に書かれていない....



「grepやawkを使うと、ファイル中のすべてが検索対象になってしまい困っております」ってあるけど
・なにがどう「困る」のか, さっぱりわからない.
・ファイル中の「検索対象の部分」と「検索対象でない部分」を区別する方法がどこにも書かれていない.

ということで, とりあえずこれらを明確にしてください.

あと, 「変数に入れる」ってどういうことでしょうか? 該当するものが複数あったら, どうしたらいいんでしょうか?
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

QN-04CのGoogle検索履歴の削除

ホーム画面上にあるGoogle検索で、文字を入力しようとすると過去の検索履歴が表示されるのですが、この検索履歴を削除する方法を教えて下さい。

(1)Google検索ウィジェットをタップし、検索画面をひらきます
 →このときに表示される検索履歴を削除したいのです!
(2)MENUボタン押下
(3)「検索設定」押下
(4)「Google検索の設定」押下
(5)「入力候補の表示」にチェックを入れない
 →チェックを入れない場合、「検索履歴」はグレーになっていて押下できない。
以上の操作では検索履歴は削除されません。
仮に、
(5)「入力候補の表示」にチェックを入れる
 →「検索履歴」はチェック入れられるようになるが、検索履歴を表示したくないので、チェックは入れない。
というようにしても検索履歴は残ったままで削除されません。
さらに、「検索履歴の管理」を押下すると「ウェブ履歴を利用すれば、検索がさらに便利に」というサイトが開きますが、このサイトから行えば検索履歴が削除されるのか不明です。
よろしくお願い致します。

Aベストアンサー

履歴消しゴムを使わないと削除出来ないです。
履歴消しゴム
https://play.google.com/store/apps/details?id=jp.androdev.historyeraser&feature=search_result#?t=W251bGwsMSwxLDEsImpwLmFuZHJvZGV2Lmhpc3RvcnllcmFzZXIiXQ..

Qperl 下記スクリプトは正常に動きますか?

今まで長い間、何か勘違いしていたのか、条件が2つ以上になると、
長い間このように書いていたのですが、
if( ($a%2==1 && $b==1) && ($c eq 10 && $d == 5) ) {
print "ok";
}

下記スクリプトでも正常に動作しますか?
if( $a%2==1 && $b==1 && $c eq 10 && $d == 5){
print "ok";
}

Aベストアンサー

どちらも同じ意味です. 同じですが....

$c eq 10
って条件が何をしたいのかわからん. 「どうなるか」はもちろんわかるけど, 「どうしてそう書いたのか」がわからない.

Q検索履歴の削除

gooでもyahooでも検索の履歴の削除の仕方がわかりません・・・
ツールで閲覧履歴の削除はできるのですが検索履歴が削除されません!!
どうしたらいいんでしょうか???

Aベストアンサー

こちらの方法で如何ですか
http://121ware.com/qasearch/1007/app/servlet/qadoc?QID=003076
http://121ware.com/qasearch/1007/app/servlet/qadoc?QID=009174

Qperl:ループのカウンタ変数の値を保持したい。

While文のループのなかにfor文でループをまわしているスクリプトなのですが、
forの中でカウンタ変数をつくり、ループ回数を計測しております。
またforの中である条件を満たした際に、lastでforを抜け、引き続きWhileのループを継続するという処理をしております。

$i=0;
While(○○){
処理1
   for(××){
処理2
$i++;
     if($i >=100){
 処理3
      last;
}
}
}

ここで、一度for文のif文で一度forループを抜け、Whileでループをし、またforループに突入した際に、前回forループでカウントした$iの値を保持したまま、そのつづきから$iのカウンタを動作させたいのですが、$iの値はforループを抜けるとリセットしてしまいます。

このような場合、どうすれば$iの値を保持できますでしょうか。
お詳しい方、宜しくお願い致します。

※ネストがうまく表現できず、みずらくてスミマセン。

While文のループのなかにfor文でループをまわしているスクリプトなのですが、
forの中でカウンタ変数をつくり、ループ回数を計測しております。
またforの中である条件を満たした際に、lastでforを抜け、引き続きWhileのループを継続するという処理をしております。

$i=0;
While(○○){
処理1
   for(××){
処理2
$i++;
     if($i >=100){
 処理3
      last;
}
}
}

ここで、一度for文のif文で一度forル...続きを読む

Aベストアンサー

Perlのfor(式1 ; 式2; 式3 ) の 式1 ; 式2; 式3 いずれかを省略することができます。
また、
for(式1 ; 式2; 式3 ) { 処理 }

式1;
while(式2) {
処理
式3
}
と(ほぼ)同じです。


これらを考えて、変数が初期化されないようにすればいいのではないでしょうか。


> $iの値はforループを抜けるとリセットしてしまいます。

for文を抜けても、変数の値は保持されます。
リセットされるのは、リセットするようにプログラムに書いてあるからです。
for(××){
って省略してありますけど、ここで for($i=0;〜) ってやってませんか?

Q検索履歴の削除

Yahooで、いつも検索しているのですが、
パソコンによって、検索の窓をダブルクリックすると過去の検索文字が残っているパソコンがあります。
アドレス欄は空っぽで、残っていません。
ちなみに0SはXPです。
人に私の検索履歴を見て欲しくないので、削除したいのですが、
履歴の削除は知っていますが、検索履歴の削除がわかりません。
削除方法を教えていただけないでしょうか。
よろしくお願いいたします。

Aベストアンサー

はじめまして。

>履歴の削除は知っていますが、検索履歴の削除がわかりません。

オートコンプリートの事ですね。

以下の様に「オートコンプリートをクリア」して下さい。↓
http://www.katch.ne.jp/~aok/contents/privacy_security/018.html
また、
今後使用しないのであれば
「オートコンプリートの使用目的」の(レ)をはずして下さい。

QPerlで指定のディレクトリ以下のファイル名を全て表示させるスクリプト

Perlで指定のディレクトリ以下のファイル名を全て表示させるスクリプトを考えておりますが、思いつきません。WindowsとLinuxの両方で利用たいです。
何かよいサンプルはありませんか?

よろしくお願いします。

Aベストアンサー

指定ディレクトリ以下を再帰的に処理するならこんなのは
どうでしょう

sub dirtree {
  my $path = shift;

  opendir(DIR, $path);
  my @dirs = grep !/^\.\.*$/, readdir(DIR);
  closedir(DIR);

  for(my $i=0; $i<@dirs; $i++){
    my $fullname = $path . '/' . $dirs[$i];
    if(-d $fullname){
      $dirs[$i] = ' ' . $fullname; # ソート用にディレクトリを' 'でマーク
    }else{
      $dirs[$i] = $fullname;
    }
  }

  for my $fullname (sort @dirs){
    if($fullname =~ s/^ //){
      dirtree($fullname);
    }else{
      #******************************
      # ここに目的の処理を記述
      #******************************
      if($fullname =~ /\.html$/){
        print "$fullname\n";
      }
    }
  }
}

指定ディレクトリ以下を再帰的に処理するならこんなのは
どうでしょう

sub dirtree {
  my $path = shift;

  opendir(DIR, $path);
  my @dirs = grep !/^\.\.*$/, readdir(DIR);
  closedir(DIR);

  for(my $i=0; $i<@dirs; $i++){
    my $fullname = $path . '/' . $dirs[$i];
    if(-d $fullname){
      $dirs[$i] = ' ' . $fullname; # ソート用にディレクトリを' 'でマーク
    }else{
      $dirs[$i] = $fullname;
    }
  }

  for m...続きを読む

Q検索履歴削除方法

Yahoo!ホームページでの検索履歴削除は
「ツール」→「インターネットオプション」→「コンテンツ(タブ)」→「オートコンプリート」で履歴削除できましたが、IEに接続した際にアドレスを入力する部分の下の検索ボタンから検索した場合の履歴の削除はどうやるのでしょうか。
説明が分かりづらいと思いますが、ご教示願います。

Aベストアンサー

★履歴の削除はレジストリで行えます。
・毎回、パソコン起動時に履歴を削除したいのならばフリーソフトの『窓の手』で
 行えます。→http://www.asahi-net.or.jp/~vr4m-ikw/
・また、『インターネット・オプション』の『オートコンプリート』で『Webアドレス』
 のチェックを外せば履歴は残りません。
・それでは、レジストリでの履歴削除方法を紹介します。

操作:
・まず、すべての『インターネット・エクスプローラ』を終了して下さい。
・『Windows』+『R』キーを押して、『regedit』と入力してレジストリ・エディタを
 起動して下さい。→やたらに削除などの操作をしなければレジストリ操作は安全!
・HKEY_CURRENT_USER
 └Software
  └Microsoft
   └Internet Explorer
    └TypedURLs を開く⇒インターネット・エクスプローラの『アドレス・バー』履歴
・右画面で『url1』~『url??』の名前がありますよね。数字の連番です。
・上記の名前を全て削除すれば履歴をクリアできます。
・削除するときは、『url1』~『url??』をシフトキーを押しながら選択して右メニュー
 から削除します。
・削除したら、レジストリ・エディタを終了します。
・以上。おわり。→安全性を求めるのなら、または自動化したい場合は『窓の手』を
 ダウンロードしてインストールしましょう。便利です。私も使っています。

参考URL:http://www.asahi-net.or.jp/~vr4m-ikw/

★履歴の削除はレジストリで行えます。
・毎回、パソコン起動時に履歴を削除したいのならばフリーソフトの『窓の手』で
 行えます。→http://www.asahi-net.or.jp/~vr4m-ikw/
・また、『インターネット・オプション』の『オートコンプリート』で『Webアドレス』
 のチェックを外せば履歴は残りません。
・それでは、レジストリでの履歴削除方法を紹介します。

操作:
・まず、すべての『インターネット・エクスプローラ』を終了して下さい。
・『Windows』+『R』キーを押して、『regedit』と入力してレ...続きを読む

Qperlを用いた特定文字列間の抽出方法について 下記のテキストファイル、test1.logからst

perlを用いた特定文字列間の抽出方法について

下記のテキストファイル、test1.logからstart〜end間を抽出するpealを作ろうと思っています。

$datafile="test1.log";
open(FH, $datafile);

@list = <FH>;

while (<FH>) {
'print if /^start$/ .. /^end$/';
}

ですが、実行してもエラーにはなりませんが何も出力されません。
どこに問題があるのかが分かりません。
最終的にはカレントディレクトリにある複数のtest1.logと同様の.logファイルを
一括で処理したいと思っています。

test1.logファイルの内容
start
aaa
bbb
ccc
end
eee
fff
ggg

分かる方がいらっしゃいましたら、お知恵をお借りしたくよろしくお願いいたします。

Aベストアンサー

> @list = <FH>; # ファイルポインタがファイルの末尾に移動

> while (<FH>) { # ポインタがファイルの末尾なのでループを実行せずに終了
>  print if /^start$/ .. /^end$/;
> }

ファイルの読み取りは1度だけですので、再オープンするか、読み取った @list を利用するなどが必要です。

(1) ファイルの再オープン
@list = <FH>;
open FH, $datafile or die;
while (<FH>) {

(2) @list の利用
@list = <FH>;
while ($_ = shift @list) {

(3) @list の作成を止める
# @list = <FH>;
while (<FH>) {

QMSNホームページのウェブ検索履歴削除方法がわからない

MSNホームページのウェブ検索の履歴削除方法が分かりません。MSNサーチの履歴の削除はウィンドウの左のMANロゴをクリックして履歴の削除ができるのは理解していますが,MSNホームのウェブ検索の履歴削除がどうしてもできません。どなたか教えてください。

Aベストアンサー

ツール

インターネットオプション

コンテンツ

オートコンプリート

フォームのクリア

これで消えます。すべてのフォームに記入している情報が削除されます。
googleとか掲示板での名前とかがそれにあたります。
なんかやばそうに聞こえますがそんなことはありません。

Qperl 配列名変数指定するには

perlプログラムで
for文で ループ分の配列定義するには どうしたらよいですか?

下記のようなことができないかと 考えております。
for(my $i = 0; $i < $file_no; $i++){
my @{"segments$i"} =(); #配列定義
my ${"line$i"}="";     #変数定義
my %{"hash$i"}= ();    #ハッシュ定義
open(ARG1,$ARGV[$i]);
while(<ARG1>){
${'line'.$i} = $_;
chomp ${'line'.$i};
@{'segments'.$i} = split(/\t/,${'line'.$i});
       ${'hash'.$i}{${'segments'.$i}[0]}=${'segments'.$i}[1];
    }
close(ARG1);
}
#下記で、その後 各ハッシュに設定したデータをもとに いろいろ計算したい
foreach my $a (keys %{'hash'.$i}){
・・・


今は、Can't declare array dereference in "my" at test.pl line XX, near "} =" と 配列定義でエラーとなり処理できません。

perlプログラムで
for文で ループ分の配列定義するには どうしたらよいですか?

下記のようなことができないかと 考えております。
for(my $i = 0; $i < $file_no; $i++){
my @{"segments$i"} =(); #配列定義
my ${"line$i"}="";     #変数定義
my %{"hash$i"}= ();    #ハッシュ定義
open(ARG1,$ARGV[$i]);
while(<ARG1>){
${'line'.$i} = $_;
chomp ${'line'.$i};
@{'segments'.$i} = split(/\t/,${'line'.$i});
       ${'hash'.$i}{${'segments'.$i}[0]}=${'segments'.$i}[1];
    ...続きを読む

Aベストアンサー

えぇっと.... わざわざそんな面倒なことをする理由が思いつかない. 配列とリファレンスを使えば同じことができる. たとえば「lineほげほげ」は, 配列を使って
${'line'.$i} = $_;
の代わりに
$line[$i] = $_;
とすればより簡単になるのでは.

ところで, forループの中で my するとその変数は「forループの外」では使えないような気がするんだが....


人気Q&Aランキング