我收到一个管道分隔格式的消息文件。一条消息行非常长,接近6000。并且总文件大小超过6GB。以下是该文件的示例格式。需要解析文件并将所有内容放入一行。
我需要从数据中间删除新行字符:
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
寻址新行之后的所有行;!
反转选择,因此仅当模式空间中两行中的第二行不以File_Name
s/\n/ /
用空格替换行之间的换行符P
打印模式空间中的第一行D
删除换行符之前的所有内容并开始新的循环,第二行仍在模式空间中(附加到下一行以产生一对新行)
请注意,这仅适用于连接两条线。如果行可以分成更多行,我们需要添加一个循环或以不同的方式进行。
答案2
这是另一个版本,使用perl
它将从文本中删除多个新行:
perl -pe 's/\n//' abc.txt | perl -pe 's/(.)File_Name/\1\nFile_Name/g'
它首先从文本中删除所有换行符,然后在每次出现“File_Name”之前插入新行(当“File_Name”前面至少有一个字符时)。
如果您需要清理例如多个空间,您可以通过更多管道:
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";