テキストブロックの抽出と比較

テキストブロックの抽出と比較

ブロックで構成されたファイルに集計されたデータがあります。

---- BLOCK ONE ----
some data
another data
more data
more data
-------------------

---- BLOCK two ----
some data
another data
-------------------

---- BLOCK THREE ----
some data
another data
more data
-------------------

など。総ブロック数は約2000個です。

項目(データ行)が4つ未満のブロックを抽出する必要があります。これを行う方法を知ってください(Perlが好ましいです)。

ベストアンサー1

$ perl -00 -F'\n' -n -e '
  $file = shift @F;
  pop @F;
  if (@F < 4) {
    $file =~ s/^---- | ----//g;
    open(OUT, ">", $file.".txt");
    print OUT join("\n", @F), "\n"
  }' input.txt

-00このperl 1行ステートメントは、短絡モードで入力を読み込み(複数の改行で区切られている)、-F自動的に改行の入力を@ F配列に分割し、-n入力を印刷せずに自動的に読み取るために使用されます(に似ていますsed -n)。

まず、Shiftを使用して@Fの最初の要素を$ file変数に入れます。その後、pop @ Fは最後の要素(-------------------)を削除します。残りの要素が4つ未満の場合は、$ fileから合計を---- 削除し、書き込み用に ----"$ file.txt"を開き、配列の残りの部分をそのファイルに印刷します。

これらのファイル名が気に入らない場合は、演算子を使用する$file = sprintf "file%04i.txt", ++$counter代わりにブロック内でカウンタ変数を増やすなど、他の方法を使用できます。ifs///

---- BLOCK...ただし、ヘッダーとフッターを維持するには、------*行をに置き換えてテストをに変更します。shiftpop$file = $F[0]ifif (@F < 6)

出力例(tailファイル名印刷用):

$ tail BLOCK*.txt
==> BLOCK THREE.txt <==
some data
another data
more data

==> BLOCK two.txt <==
some data
another data

スタンドアロンスクリプトと同じですが、カウンタを使用してファイル名を生成します。

$ cat split-blocks.pl
#!/usr/bin/perl

use strict;
my $counter;

$/='';

while(<<>>) {
  my @lines = split /\n/;
  my $file = shift @lines;
  pop @lines;

  if (@lines < 4) {
    $file = sprintf 'file%04i.txt', ++$counter
    open(OUT, ">", $file) || die "couldn't open $file for write: $!\n";
    print OUT join("\n", @lines), "\n"
  }
};

$ ./split-blocks.pl input.txt

$ tail file*
==> file0001.txt <==
some data
another data

==> file0002.txt <==
some data
another data
more data

おすすめ記事