Perl 将两种模式之间的多行数据合并为一行输出

Perl 将两种模式之间的多行数据合并为一行输出

文件1

pure info:       myjob-relaed_rawmaterila
Timings:              Full
pure info:       Check-platform-Log-90Days
Timings:              Full
Timings:              Incremental
pure info:       Check-vitorydows-Log-90Days
Timings:              Full
Timings:              Incremental
pure info:       Note_michael
Timings:              Full
pure info:       adhoc-activity-myjob-platform
Timings:              Full
pure info:       adhoc-activity-myjob-vitory
Timings:              Full
pure info:       adhoc-myjob-platform-03
Timings:              Full
Timings:              Full-1month
pure info:       adhoc-onetime-myjob-hotcase
Timings:              Full
pure info:       adhoc-onetime-myjob-platform

需要输出

pure info: myjob-relaed_rawmaterila Timings:  Full
pure info: Check-platform-Log-90Days Timings:  Full Timings:  Incremental
pure info: Check-vitorydows-Log-90Days Timings:  Full Timings:  Incremental
pure info: Note_michael Timings:  Full
pure info: adhoc-activity-myjob-platform Timings:  Full
pure info: adhoc-activity-myjob-vitory Timings:  Full
pure info: adhoc-myjob-platform-03 Timings:  Full Timings:  Full-1month
pure info: adhoc-onetime-myjob-hotcase Timings:  Full

我试过

cat file1|sed -e 's/^ //' -e 's/$// 
cat file1|perl -pe's/\n/ / if $.  % 3' 

但这只是在一行中打印 2 行,如果有额外的Timings条目,那么这就是锯齿形输出。

我怎么解决这个问题?

答案1

关于您的 perl 解决方案:由于 -p 构造,提供的脚本逐行处理输入。这使得连接线变得困难,因为线不知道接下来会发生什么。

当您将输入作为一个字符串处理时,您可以进行智能替换来连接行。这是一个类似于您调用 perl 的方式的示例:

perl -e 'local $/;my $data = <>; $data =~ s/\nTiming/ Timing/g ; print $data' file1

该脚本读取一个字符串 ($data) 中的整个输入,并用空格替换 Timing 之前的换行符。对于所有出现的情况都是如此(替换后 g 切换为全局)

答案2

GNU sed 解决方案:

sed -rz 's/\n(Timings)/ \1/g' file1

答案3

Perl 单行版本:

perl -0777 -pe 's/\n(?=Timings:)/ /g' file

-0777 选项强制 Perl 将整个文件转换为$_.然后,出现在“Timings:”之前的所有换行符都将被替换。

如果“Timings”旁边还有其他标题,您可以使用否定前瞻:

s/\n(?!pure info:)/ /g

答案4

使用

perl -ne '
    my $s = $_ if
        /pure info:\s+myjob-relaed_rawmaterila/
        ..
       /pure info:\s+adhoc-onetime-myjob-hotcase/;
    do{
        chomp;
        s/\s{3,}/ /;
        $_ = sprintf "%s ", $s;
        s/pure info/\n$&/g;
        print
    } for $s;
    END{ print "\n" }
' file1

相关内容