
パイプで区切られた形式のメッセージファイルを受け取りました。メッセージ行の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";