【问题标题】:Remove what follows Nth occurrence Using one-liners使用单行删除第 N 次出现之后的内容
【发布时间】:2013-11-11 14:17:43
【问题描述】:

我想删除任何字段中第四次出现字符“:”之后的内容。看例子:

输入:

1 10975     A C    1/1:137,105:245:99:1007,102,0   0/1:219,27:248:20:222,0,20 
1 19938     T TA   ./.                             1/1:0,167:167:99:4432,422,0,12,12
12 20043112 C G    1/2:3,5,0:15:92                 2/2:3,15:20:8

预期输出:

1 10975     A C    1/1:137,105:245:99   0/1:219,27:248:20 
1 19938     T TA   ./.                  1/1:0,167:167:99
12 20043112 C G    1/2:3,5,0:15:92      2/2:3,15:20:8

所以基本上任何具有“:”的字段,其第四次出现之后的内容都应该被删除。请注意,第三行没有任何变化,因为“:”只出现了三次。我已经尝试并找到了一个解决方案(不好),它不仅适用于第一行而不是第二行,因为它有更多的逗号“,”

不完整的解决方案:

sed 's/:[0-9]*,[0-9]*,[0-9]*//g'

提前致谢

【问题讨论】:

    标签: perl sed awk gawk nawk


    【解决方案1】:

    Sed:

    sed -r 's/((:[^: \t]*){3}):[^ \t]*/\1/g' file | column -t
    

    Perl:

    perl -pe 's/((:\S*){3}):\S*/$1/g' file | column -t
    

    【讨论】:

      【解决方案2】:

      使用sed

      sed -r 's/((:[^ ]*){3}):[^ ]*/\1/g' file
      

      输出:

      1 10975     A C    1/1:137,105:245:99   0/1:219,27:248:20 
      1 19938     T TA   ./.                             1/1:0,167:167:99
      12 20043112 C G    1/2:3,5,0:15:92                 2/2:3,15:20:8
      

      使用perl

      perl -pe 's/((:\S*){3}):\S*/$1/g' file
      

      【讨论】:

      • 为什么不perl -pe 's/((:\S*){3}):\S*/$1/g'
      【解决方案3】:

      在字段 5 到最后一个字段中,这将删除正则表达式 :[^:]+ 的第四次出现

      < file.txt awk '{ for (i=5; i<=NF; i++) $i = gensub(/:[^:]+/, "", 4, $i) }1' | column -t
      

      在字段 5 到最后一个字段上,这将删除第四个 : 之后的所有内容

      < file awk '{ for (i=5; i<=NF; i++) $i = gensub(/((:[^:]+){3}).*/, "\\1", 1, $i) }1' | column -t
      

      说明:

      重新阅读您的问题后,第二个解决方案可能就是您正在寻找的。第一个解决方案查找冒号后跟一个或多个字符而不是冒号并将它们删除。 gensub() 的第三个参数描述了要替换的正则表达式的匹配项。所以 4 告诉gensub() 删除模式的第四个匹配项。第二个解决方案,查找第一个答案中描述的三组正则表达式。在这一点上,值得一提的是gensub() 提供了一个使用sub()gsub() 不可用的附加功能。这是在替换文本中指定正则表达式组件的能力,就像其他语言如何使用括号来执行捕获一样。 gensub() 是一个非常强大的命令,只有使用 GNU awk 才能使用。 here 提供的描述和示例非常有用。 HTH。

      结果:

      1   10975     A  C   1/1:137,105:245:99  0/1:219,27:248:20
      1   19938     T  TA  ./.                 1/1:0,167:167:99
      12  20043112  C  G   1/2:3,5,0:15:92     2/2:3,15:20:8
      

      【讨论】:

      • 另外,如果您想要制表符分隔输出,只需将| column -t 更改为OFS="\t"
      • 非常感谢它的工作。能否请您解释一下 gensub 命令以及 gensub、sub 和 gsub 之间的区别?
      • @user1421408:我添加了一些关于这些命令的解释。请参阅 cmets。 HTH。
      【解决方案4】:
      perl -lane 's/(.*?:.*?:.*?:.*?):.*/$1/g  for @F ; printf "@F"."\n"' your_file
      

      【讨论】:

        猜你喜欢
        • 2020-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-27
        • 1970-01-01
        • 1970-01-01
        • 2021-08-29
        相关资源
        最近更新 更多