• 締切済み

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

次のようなテキストファイルがあります。 (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  などの行まであっても同じやり方でできると思います。) よろしくお願いします。

  • ding2
  • お礼率97% (101/104)
  • Python
  • 回答数6
  • ありがとう数5

みんなの回答

  • 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

  • エクセルの行番号欄が下2ケタしか表示されません

    エクセル2007で作ったファイルがあるのですが、行番号の欄の巾が狭くて、下2ケタしか表示されません。しかも巾が狭いため2ケタ目は数字の半分しか見えない状態です。解決法を教えてください。 よろしくお願いいたします。

  • Perlで特定行から特定行までを抜き出したい

    皆さんのお知恵をお貸し頂ければ幸いです。 Perlで以下のようなことをしたいと考えています。 例えば、次のようなテキストファイルがあったとします。 example.log ================================== aaaa hogehoge test okok perl script ================================== 上記ファイルを読み込んで、「hogehoge」から「perl」の間に挟まれた行だけ抜き出したいのです。 イメージとしては、読み込んだファイルを配列に入れて、一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。 このような場合、どういう風にすればいいのでしょうか? 恐れ入りますが、ご教授頂ければ幸いです。 それでは、どうぞよろしくお願い致します。

    • ベストアンサー
    • Perl
  • エクセルの行番号の欄の巾が狭く2ケタしか見れません

    エクセル2007で作ったファイルがあるのですが、行番号の欄の巾が狭くて、下2ケタしか表示されません。しかも巾が狭いため下図のように2ケタ目は数字の半分しか見えない状態です。解決法をよろしくお願いいたします。

  • 行番号をコピーできるフリーソフト

    行番号をつけたテキストをコピー(印刷ではありません、いわゆるコピペです) できるソフト ご存知の方教えてください。 日本語で御願いします。 ※それらを(複数)ワードなどで まとめたりしたいのです。(テラパットでは、行番号が印刷できると思いますが、 それは単独のためNGです) ---------------- 1 2 3 4 5 6 7 ------------ ---------- 1 2 3 4 5 ------------ 上記の2つのファイルを1つのファイルにする。 -------------------------- プログラムNO1 ○○○○○(説明) 1  2 3 4 5 6 7 プログラムNO2 ○○○○○(説明) 1 2 3 4 5 -------------------- ※空白ですが実際は何か書いてあると想定して下さい。 ※出来れば 数字の桁が調整される(1→01や001に出来る)ソフトを希望します

  • perlで特定行から特定行までを抜き出しor置換

    perlで以下のようなことをしたいと考えています。 以下のことを、コマンドラインから「perl ~」という形で 実行したいのですが、どのよにすればよいでしょうか。 1.特定行から特定行までを抜き出し 2.特定行から特定行の範囲で文字列置換 例えば、次のようなテキストファイルがあったとします。 example.txt ================================== #START aaaa hogehoge test okok perl script #END ================================== 上記ファイルを読み込んで、 1.「#START」から「#END」の間に挟まれた行だけ抜き出し 2.「#START」から「#END」の間で、「test」を置換 のです。 sedで言うところの sed -e '/#START/,/#END/ s/YYYYMM/201603/g' test.txt をやりたいのです。

    • ベストアンサー
    • Perl
  • 16ケタの数値の下一桁が”0”になってしまう。

    CSVファイルに出力されたテキストファイルをエクセルで読み込みました。その時に”1000058216333401”と秀丸などのテキストエディタでは表示されるテキストが、エクセルだと”1000058216333400”と下一桁が必ず”0”となっています。ほかにも1000件程度のデータで16桁のデータの必ず下一桁が”0”となってしまいます。 ”1000058216333401” このようにCSVファイルに書かれている通りのデータにする日はどうしたらよいでしょうか? どうぞ、ご教授の程よろしくお願い致します。

  • 文字列を複数行の先頭にいれたいです。

    下記のようなテキストファイル(氏名の下は不特定数行)があります。 山田 hogehoge hogehoge hogehoge hogehoge 田中 hogehoge hogehoge 鈴木 hogehoge これを下記のようなテキストに変換したいのですがsedとかでできないでしょうか?sedは使える環境です。よろしくお願いいたします。 山田hogehoge 山田hogehoge 山田hogehoge 山田hogehoge 田中hogehoge 田中hogehoge 鈴木hogehoge

    • ベストアンサー
    • Perl
  • 携帯電話の番号で下4桁の数字が

    携帯電話の番号で下4桁の数字が 選べますが、必ずしも4桁にしなきゃ いけないのですか? 下の数字を3桁にすることは できますか?

  • Perlで行をさかのぼって削除する方法を教えて下さい

    ActivePerl5.8.4にて、以下の規則に従い、テキストファイルから複数行を削除しようとしています。 ・1つの行はアルファベットと数字から成っており、アルファベットはA,B,Cの順に出現する。A,B,Cの行で一かたまり。 ・数字部分が全く同じかたまりが出現すると、後で出現したかたまりを削除する。 ・数字部分が全く同じかたまりが出現するときは、必ず連続で出現する。 下のような感じです。(スペースの都合で「\n」をつけましたが、実際には改行までが1行に書かれているテキストファイルを読み込みます。) 【入力】 A 1\nB 2\nC 3\nA 1\nB 2\nC 3\nA 1\nB 2\nC 2[EOF] 【出力】 A 1\nB 2\nC 3\nA 1\nB 2\nC 2[EOF] すぐに思いついた方法はこんな感じです(まだ勉強不足のため、コードではあらわせません)。  1.ファイルの1行ずつ読み込む  2.A,B,Cをキーにして数字をハッシュに格納  3.2回目のCまで読み込んだところで1つ前のハッシュと比較  4.AからCの数字がすべて同じだった場合に、現在の行(2つめのCを読み込んでいる)とその前2行を削除(実際にはnextでprintを飛ばす) ところが、4の、さかのぼって行を削除する方法が思いつきません。 なにぶんperlの勉強を始めたばかりで突っ込み所満載のロジックだとは思いますが、解決策をぜひご教示ください。

    • ベストアンサー
    • Perl
  • Memoコントロールの1行あたりの格納可能桁数は?

    BCB5を使用しています。 Memoコントロールにテキストを表示するテストプログラムを作っています。 表示するテキストはFileから読み込んでいます。 (本番では、Fileのほか、クリップボードからの貼り付けもあります。) MemoコントロールのWordWrapはfalseとなっています。 ところが、1行あたりの桁数が多い場合は1024桁を超える部分は改行されてしまいます。 1024桁を超えていても改行せずに1行の中に収めたいのですが、可能でしょうか?