• 締切済み

番号のある行とその一つ下の行を抜き出していく

次のようなテキストファイルがあります。 (hogehoge の部分はそれぞれの行によって全く異なる文章です) 253 hogehoge hogehoge (間に数百行あり) 101 hogehoge hogehoge (間に数行あり) 100 hogehoge hogehoge (間に数行あり) 99 hogehoge hogehoge (間に数百行あり) 14 hogehoge hogehoge (間に数行あり) 13 hogehoge hogehoge これから、 253 の数字がある部分でいえば 253 hogehoge の行とそのすぐ下の1行の2行ずつを 抜き出して 全てつなぎ合わせたテキストファイルを作りたいです。 どのようにすればよいでしょうか? また、2桁の数字の行が 013 hogehoge などとなっていた時は、同じことをやるのに どのようにやり方を変えればいいでしょうか? (これができれば  004 hogehoge  などの行まであっても同じやり方でできると思います。) よろしくお願いします。

みんなの回答

  • Wap58
  • ベストアンサー率33% (29/87)
回答No.6

不規則な内容のファイルを扱う 数字スペース文字列の規則を目印にする 続いて出現する文字列と2行を抜き出す 検索数字は連番で良い 検索数字は000の3桁文字でフォーマット 検索ファイル内容で不具合あるかもしれない $ perl nukidashi.pl リスト.txt use strict; #use warnings; my $end = 255; ### 検索開始数字(大きい数字から) my $start = 4; ### 検索終了数字(小さい数字まで) sub memo_1{ my @ken = @_; my $kai_1 = 0; ### 1行目を改行するなら1 my $kai_2 = 0; ### 2行目を改行するなら1 my $count_1 = 0; my $Log; open my $HK ,"$ARGV[0]" or die; my @gen = <$HK>; close $HK; for my $kan(@ken){ for(@gen){ next if $_ =~ m[\s+\n|^\n]; my $scalar_1 = [split(' '),$_]; if($kan and $scalar_1->[0] eq $kan){ $kai_1 ? $Log .= "$_" : chomp($Log .= "$_"); $count_1++; next; } if($count_1){ $kai_2 ? $Log .= "$_" : chomp($Log .= "$_"); $count_1 = 0; last; } }} $Log; } my @haire; my $count = 0; $start--; for(;$start < $end;$start++){ my $min = $end - $count; $haire[$count] = sprintf("%03d",$min); $count++; } print memo_1(@haire),"\n"; ### 手入力用 # my $jo_1 = join('\',\'',@haire); # print"$jo_1\n"; ###

ding2
質問者

お礼

ありがとうございます。 たびたびお時間を割いて作っていただきまして とてもありがたいのですが、 今回は 行番号(とその次の行)の直後が日本語から始まっていると その行番号の部分は結果に出てこなくなります。 行番号ごとに改行もなされないようですが、 あまり作り直していただくのも気の毒ですので。

  • Wap58
  • ベストアンサー率33% (29/87)
回答No.5

とりあえず動かすで勘弁して下さい デバックし出したら終わらないので #use warnings; 2行目を上記にして下さい 比較対象が無いよエラーは消えます

ding2
質問者

お礼

> 番号が振ってある行全てから2行ずつ抜き出したいです。 結局 $ for i in {253..013} ; do echo -n $i',' ; done この実行結果でできたやつをスクリプトに貼り付けました。 my @key=('253','013','004'); ###抜き出したい番号 この形式にするなら $ for i in {253..004} ; do echo -n "'"$i"'"',' ; done ですね。 途中で抜けている番号については その番号とそのすぐ下の行(空白行でもOKでした)を手作業で入力ファイルに入れるということをやりました。 そうしないと処理がそこの番号までで止まりますので。 それぞれの行番号の所で改行されるとなお良かったのですけど、 おかげさまで何とか目的にたどりつきました。 ありがとうございました!

  • Wap58
  • ベストアンサー率33% (29/87)
回答No.4

$ perl nukidashi.pl リスト.txtで行きましょう @keyに番号をシングルクォートで挟んでコロンで区切る use strict; use warnings; sub memo_1{ my @ken = @_; my $kai_1 = 0; ### 2行目を改行するなら1 my $count_1 = 0; my $count_2 = 0; my $Log; open HK ,"$ARGV[0]" or die; while(<HK>){ my $scalar = [split(' ',$_)]; if($ken[$count_1] and $scalar->[0] eq $ken[$count_1]){ chomp($Log .= "$_"); $count_2++; next; } if($count_2 > $count_1){ $kai_1 ? $Log .= "$_" : chomp($Log .= "$_"); $count_1++; } } close HK; $Log; } my @key=('253','013','004'); ###抜き出したい番号 print memo_1(@key),"\n";

ding2
質問者

お礼

たびたびありがとうございます。 まず、最初から書いておかなければならなかったと思いますが (申し訳ありません) リスト.txt には 251,250 のように途中で抜けている番号もあります。 空白行もたくさんあります。 この回答のスクリプトにおいて my @key=('253','252','249','13'); ###抜き出したい番号 というようにすれば、実行した時に Use of uninitialized value in string eq at nukidashi.pl line 15, <HK> line 69. こういうメッセージが10個くらい出てきますが ここで明示的に指定した番号の行(とそのすぐ下の行)は抜き出されます。 全て手作業で番号をここに書かなければいけないでしょうか?

  • Wap58
  • ベストアンサー率33% (29/87)
回答No.3

No.1です すいません訂正 頭が0ならシングルクォートして下さい sub memo_1{ my @ken = @_; my @ken = @_; my $count_1 = 0; my $count_2 = 0; my $Log; open my $hai ,'hoge.txt'; while(<$hai>){ my $scalar = [split(' ',$_)]; if($scalar->[0] eq $ken[$count_1]){ $Log .= "$_"; $count_2++; next; } if($count_2 > $count_1){#print"End $_\n"; $Log .= "$_"; $count_1++; } } $Log; } close $hai; print memo_1(253,'013','004'),"\n";

ding2
質問者

お礼

たびたびありがとうございます。 > 私としては > pythonでもperlでもawkでも > どれでも大丈夫です。 すみません、書き方が悪かったのかもしれませんけど 私はこういった言語のどれに対してもほとんど知識がありません。 自分でも少し調べて読み解こうとしてみようとは思いますが、自信はありません。 この回答のスクリプトの print memo_1(253,'013','004'),"\n"; この行のみを print memo_1(253,13),"\n"; こう変えて実行しました。 $ perl nukidashi.pl 253 長い日 オプション 13 始め カヤック こういう結果です。 番号が振ってある行全てから2行ずつ抜き出したいです。 > my @hai <= サンプルなので削除してください ここをいじろうと思っても どういう風にいじれば適切か分かりませんし。

  • Wap58
  • ベストアンサー率33% (29/87)
回答No.2

No.1です my @hai <= サンプルなので削除してください 読み込むファイルをopenして ループに取り込んでください そして検索数字をmemo_1()に送る

  • Wap58
  • ベストアンサー率33% (29/87)
回答No.1

すんません、Python知りません Perlなんで書き換えてください sub memo_1{ my @ken = @_; my @hai = ( # 検索文字列 '99 AAA88A','88 BBB77B', '77 CCC66C','66 DDD55D', '55 EEE44E','44 FFF33F', '33 GGG22G','22 HHH11H', '11 MMM00M','00 NNN99N'); my $count_1 = 0; my $count_2 = 0; my $Log; for(@hai){ if($ken[$count_1] and $_ =~ m[^$ken[$count_1]]){ $Log .= "$_, "; $count_2++; next; } if($count_2 > $count_1){ $Log .= "$_, "; $count_1++; next; } } $Log; } print memo_1(88,55,22),"\n";

ding2
質問者

お礼

ありがとうございます。 なぜかこの質問はpythonのコーナーが指定されています。 私としては pythonでもperlでもawkでも どれでも大丈夫です。 回答くださったperlスクリプトを nukidashi.pl という名前で保存して リスト.txt という入力ファイルに作用させてみたのですけど $ perl nukidashi.pl リスト.txt 88 BBB77B, 77 CCC66C, 55 EEE44E, 44 FFF33F, 22 HHH11H, 11 MMM00M, こういう実行結果になります。 どこがマズイのでしょうか?

関連するQ&A