開始テキスト文字列を使用して、行の途中から新しい行を削除します。

開始テキスト文字列を使用して、行の途中から新しい行を削除します。

パイプで区切られた形式のメッセージファイルを受け取りました。メッセージ行の1つは非常に長く、6000に近いです。そして、合計ファイルサイズが6GBを超えています。以下は、このファイルのサンプル形式です。ファイルを解析し、すべてを1行に入れる必要があります。

データの途中で改行文字を削除する必要があります。

File: abc.txt
File_Name|abc.txt|date|04212019|this is one full line|Client_name|Whole
File_Name|abc.txt|date|04212019|half data is good
File_Name|abc.txt|date|04212019|Sample data
is split|Client_Name|Marshals
File_Name|abc.txt|date|04212019|this is good again|Processing_date|03282019
File_Name|abc.txt|date|04212019|line is not good 
again|Processing_date|04232019

私はデータが次のようになりたいです。

File_Name|abc.txt|date|04212019|this is one full line|Client_name|Whole
File_Name|abc.txt|date|04212019|half data is good
File_Name|abc.txt|date|04212019|Sample data is split|Client_Name|Marshals
File_Name|abc.txt|date|04212019|this is good again|Processing_date|03282019
File_Name|abc.txt|date|04212019|line is not good again|Processing_date|04232019

私はLinuxを使用しています。

メモリ不足エラーが発生するperl -efを試してみました。

答え1

File_Nameもしそうなら、?で始まらない行を前の行にリンクしますか?

では、パターンをsed使用して次の操作を実行できますN;P;D

sed 'N;/\nFile_Name/!s/\n/ /;P;D' abc.txt
  • Nパターン空間に次の行を追加する
  • /\nFile_Name/File_Name新しい行の後のすべての行を指定します。!パターン空間の2行のうち2行目が次から始まらない場合にのみ選択を反転します。File_Name
  • s/\n/ /行間の改行をスペースに置き換える
  • Pパターン空間の最初の行を印刷します。
  • D改行の前のすべての項目を削除し、2行目がまだパターンスペースにある状態で新しいループを開始します(新しい行ペアを作成するには、次の行に追加されます)。

これは、2本のワイヤを接続する場合にのみ機能します。行をより多くの行に分割できる場合は、ループを追加するか、別の方法で実行する必要があります。

答え2

以下は、perlテキストから複数行の新しい行を削除する別のバージョンです。

perl -pe 's/\n//' abc.txt | perl -pe 's/(.)File_Name/\1\nFile_Name/g'

まず、テキストからすべての改行を削除し、次に「File_Name」が表示されるたびに(「File_Name」の前に少なくとも1文字が続く場合)、その前に新しい行を挿入します。

たとえば、複数のスペースを清掃する必要がある場合は、より多くのパイプを渡すことができます。

perl -pe 's/\n/ /' abc.txt \
| perl -pe 's/(.)File_Name/\1\nFile_Name/g' \
| perl -pe 's/ +/ /g'

答え3

何らかの理由で-peバージョンがクラッシュした場合、スタンドアロンプ​​ログラムperlは次のようになります。 Stripper.pm これは、前の行の内容に基づいて操作を実行する標準的な方法です。以下を実行してこれを実行できます。

perl stripper.pm <abc.txt >new_abc.txt

#!/usr/bin/perl
my $previous = <STDIN>;

if( defined $previous ){
    chomp $previous;
};

while( $line = <STDIN> ){
    chomp $line;

    unless( $line =~ m/^File_Name/ ){
        $previous .= $line;

    } else { 
        print STDOUT "$previous\n";
        $previous = $line;
    }
}

print STDOUT "$previous\n";

関連情報