我有一个看起来像这样的文件:
2014-05-01 00:30:45,511
ZZZ|1|CE|web1||etc|etc
ZZZ|1|CE|web2||etc|etc
ZZZ|1|CE|web3|asd|SDAF
2014-05-01 00:30:45,511
ZZZ|1|CE|web1||etc|etc
ZZZ|1|CE|web2||etc|etc
ZZZ|1|CE|web3|asd|SDAF
我希望通过用管道替换换行后跟某些模式将其转换为2行。我想要:
2014-05-01 00:30:45,511|ZZZ|1|CE|web1||etc|etc|ZZZ|1|CE|web2||etc|etc|ZZZ|1|CE|web3|asd|SDAF
2014-05-01 00:30:45,511|ZZZ|1|CE|web1||etc|etc|ZZZ|1|CE|web2||etc|etc|ZZZ|1|CE|web3|asd|SDAF
我正在尝试与perl进行多行匹配:
cat file | perl -pe 's/\nZZZ/\|ZZZ/m'
但这不匹配。
我可以做perl -pe' / \ n // m'但那太多了;我需要匹配' \ nZZZ'这样只有以ZZZ开头的行才会加到前一行。
答案 0 :(得分:2)
您只需使用-0777
开关指示啜食模式,因为您正在使用正在尝试匹配多行的正则表达式。
完整的解决方案:
perl -0777 -pe 's/\n(?=ZZZ)/|/g' file
切换:
-0777
:slurp files whole -p
:为输入文件中的每一行创建一个while(<>){...; print}
循环。 -e
:告诉perl
在命令行上执行代码。 <强>代码强>:
s/\n(?=ZZZ)/|/g
:用| 答案 1 :(得分:2)
如果你想避免啜食模式,试试这个:
perl -pe 'chomp unless eof; /\|/ and s/^/|/ or $.>1 and s/^/\n/' filename.txt
答案 2 :(得分:0)
答案 3 :(得分:0)
这是一个非常标准的模式。看起来像这样。输入文件的路径需要作为命令行上的参数
use strict;
use warnings;
my $line;
while (<>) {
chomp;
if ( /^ZZZ/ ) {
$line .= '|' . $_;
}
else {
print $line, "\n" if $line;
$line = $_;
}
}
print $line, "\n" if $line;
<强>输出强>
2014-05-01 00:30:45,511|ZZZ|1|CE|web1||etc|etc|ZZZ|1|CE|web2||etc|etc|ZZZ|1|CE|web3|asd|SDAF
2014-05-01 00:30:45,511|ZZZ|1|CE|web1||etc|etc|ZZZ|1|CE|web2||etc|etc|ZZZ|1|CE|web3|asd|SDAF