【问题标题】:Printing different fields from different lines从不同的行打印不同的字段
【发布时间】:2014-05-06 14:10:45
【问题描述】:

我有一个如下所示的文件

G1 A1 X 3 6 NA 7 NA NA NA 7 NA NA
G1 B1 X NA NA NA NA NA NA NA NA 7 6
G1 C1 X NA 1 3 4 NA NA NA NA NA NA
G2 D1 Y NA NA NA 1 NA NA NA NA NA NA
G2 E1 Y 2 NA NA NA NA NA NA NA NA NA
G2 F1 Y NA NA NA NA 0 NA NA NA NA NA
G1 G1 Y NA NA NA NA NA 8 7 NA NA NA
G2 H1 X NA NA NA NA NA NA NA NA NA NA

现在我想打印那些不等于 NA 的字段。同样,我不想更改第一个三列格式,但之后我想打印以逗号分隔的剩余字段,我想要的输出文件为

G1 A1 X 3, 6, 7, 7 
G1 B1 X 7, 6
G1 C1 X 1, 3, 4
G2 D1 Y 1
G2 E1 Y 2 
G2 F1 Y 0 
G1 G1 Y 8, 7 
G2 H1 X

我试过了

sed 's/NA//g' file| sed 's/\t/ /g'| sed 's/ \+/, /g'

但它也改变了前三列的格式。你能为此提出一些建议吗?

谢谢

【问题讨论】:

    标签: awk sed


    【解决方案1】:

    这里是awk

    awk '{gsub(/ NA/,"");for (i=4;i<NF;i++) $i=$i","}1' file
    G1 A1 X 3, 6, 7, 7
    G1 B1 X 7, 6
    G1 C1 X 1, 3, 4
    G2 D1 Y 1
    G2 E1 Y 2
    G2 F1 Y 0
    G1 G1 Y 8, 7
    G2 H1 X
    

    【讨论】:

      【解决方案2】:

      这已经够复杂了,我可以使用 perl。

      perl -pe '
          chomp; s/\s+/ /g; s/ $//; s/^ //;
          my ($left, $right) = /(\S+ \S+ \S+) (.+)$/;
          $right =~ s/\bNA\b//g;
          $right =~ s/^ +//;
          $right =~ s/ +$//;
          $right =~ s/ +/, /g;
          $_ = "$left $right";
          s/ *$/\n/;
      '
      

      DTRT 在您的测试用例上,比我更聪明和/或更少困倦的人可能会稍微降低它。

      【讨论】:

        【解决方案3】:

        这是使用awk的另一种方式:

        awk '{gsub(/NA/,"");$1=$1;for(i=4;i<=NF;i++)$i=(i==NF?$i:$i",")}1' file
        G1 A1 X 3, 6, 7, 7
        G1 B1 X 7, 6
        G1 C1 X 1, 3, 4
        G2 D1 Y 1
        G2 E1 Y 2
        G2 F1 Y 0
        G1 G1 Y 8, 7
        G2 H1 X
        

        或使用 GNU sed

        sed -e 's/\bNA\b//g' -e 's/ \+/ /g' -e 's/ *$//' -e 's/ /, /4g' file
        G1 A1 X 3, 6, 7, 7
        G1 B1 X 7, 6
        G1 C1 X 1, 3, 4
        G2 D1 Y 1
        G2 E1 Y 2
        G2 F1 Y 0
        G1 G1 Y 8, 7
        G2 H1 X
        

        【讨论】:

          【解决方案4】:
          sed ':a
          s/\(\([^]\{1,\} \{1,\}\)\{2\}[^ ]\{1,\}\)\(.*\) NA/\1\3/
          t a
          ' YourFile
          

          通常也应该使用通用类 [:blank:] 而不是空格字符(下面的代码),但奇怪的是在我的系统上失败了

          sed ':a
          s/\(\([^[:blank:]]\{1,\}[:blank:]\{1,\}\)\{2\}[^[:blank:]]\{1,\}\)\(.*\)[:blank:]NA/\1\3/
          t a
          ' YourFile
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-08-09
            • 1970-01-01
            • 2020-12-18
            • 1970-01-01
            • 2017-08-12
            • 2022-01-08
            相关资源
            最近更新 更多