【问题标题】:Add blank line between lines from different groups在不同组的行之间添加空行
【发布时间】:2011-05-21 19:04:48
【问题描述】:

我有一个文件A,格式为(频率、文件名、代码行):

1 file_name1 code_line1
2 file_name2 code_line2
2 file_name2 code_line3
2 file_name3 code_line4
2 file_name3 code_line5
3 file_name4 code_line6
3 file_name4 code_line7
3 file_name4 code_line8

我想将B 输出为:

1 file_name1 code_line1

2 file_name2 code_line2
2 file_name2 code_line3

2 file_name3 code_line4
2 file_name3 code_line5

3 file_name4 code_line6
3 file_name4 code_line7
3 file_name4 code_line8

基本上,文件A 包含文件中的文件名和代码行,第一个字段是频率,即文件中的代码行数。

我应该仔细阅读这些代码行文件。我发现它很乏味,如果不同文件的条目之间存在行间距,这对我来说会更容易,因此是所需的输出。

【问题讨论】:

    标签: linux shell scripting sed awk


    【解决方案1】:

    Awk 可以做到:

    awk '{if(NR > 1 && $2 != prev_two){printf "\n";} prev_two=$2; print $0}' A
    

    A 是文件名。

    【讨论】:

    • 对我来说,awk 中的 if 语句太像 C:awk 'prev != $2 {print ""} {print; prev=$2}' filename
    【解决方案2】:

    你可以使用 awk:

    awk 'BEGIN{file=0}{if (file && file!=$2) {print ""} print $0; file=$2}' fileA
    

    【讨论】:

      【解决方案3】:

      为您提供快速而肮脏的 Perl:

      $lastfile = '';
      while (<>) {
        @line = split(/\s+/);
        $filename = $line[1];
        print "\n" unless ($lastfile eq $filename);
        $lastfile = $filename;
        print;
      }
      

      用法:perl script.pl &lt; original_file.txt &gt; newfile.txt

      【讨论】:

      • 更快更脏:perl -lape 'print "" unless $F[1] eq $prev; $prev = $F[1]' file
      【解决方案4】:

      要添加到 awk 和 Perl 解决方案,一个 GNU sed 解决方案:

      $ sed -r 'N;/file_name(\w+).*\n.*file_name\1/!{s/\n/&\n/;P;s/^[^\n]*\n//};P;D' infile
      1 file_name1 code_line1
      
      2 file_name2 code_line2
      2 file_name2 code_line3
      
      2 file_name3 code_line4
      2 file_name3 code_line5
      
      3 file_name4 code_line6
      3 file_name4 code_line7
      3 file_name4 code_line8
      

      解释:

      N # Append next line to pattern space
      
      # If the numbers after the 'file_name' string DON'T match, then
      /file_name(\w+).*\n.*file_name\1/! {
          s/\n/&\n/      # Insert extra newline
          P              # Print up to first newline
          s/^[^\n]*\n//  # Remove first line in pattern space
      }
      P # Print up to newline - if we added the extra newline, this prints the empty line
      D # Delete up to newline, start new cycle
      

      【讨论】: