【问题标题】:Replace text surrounded by specific characters替换被特定字符包围的文本
【发布时间】:2013-10-05 14:41:47
【问题描述】:

我有这种类型的数据(所有大写字母都是字符串)

>A|B|C|D|E|F
test test test
test test
>A|B|C|D|E|F
test test test
test 

又想删除C、D、E:

>A|B|F
test test test
test test
>A|B|F
test test test
test

在“测试”文本中,没有出现|。我已经用sed 尝试过这个,但我无法替换两个| 之后的文本
先感谢您。

【问题讨论】:

  • 因此,在您的真实数据中,您有多字符字段,并且没有“|”分隔字段,对吗?也许发布示例输入和预期输出来反映这一点对您有用,而不是用“|”分隔的单字符字段。把它扔出去……
  • 是的,你是对的。广义样本输入可能会造成混淆。

标签: regex perl replace sed awk


【解决方案1】:

Perl 单行器,

perl -F'\|' -lane 'print /\|/ ? join "|", @F[0,1,5] : $_' file

它用| char 分割每一行并将值存储在@F 数组中。如果 line 包含 |,则从 @F 获取元素 0,1 和 5,否则保持 line 原样。

Oneliner 已解析,

perl -MO=Deparse -F'\|' -lane 'print /\|/ ? join "|", @F[0,1,5] : $_' file
BEGIN { $/ = "\n"; $\ = "\n"; }         # -l switch makes print to add newline
LINE: while (defined($_ = <ARGV>)) {    # -n switch
    chomp $_;                           # -l switch chomps newlines
    our(@F) = split(/\|/, $_, 0);       # -a switch splits on value of -F switch
    print /\|/ ? join('|', @F[0, 1, 5]) : $_;
}

【讨论】:

    【解决方案2】:
    $ cat file
    >A|B|C|D|E|F
    test test test
    test test
    >A|B|C|D|E|F
    test test test
    test
    >gene_8|GeneMark.hmm|322_aa|+|3803|4771TS28_contig03869
    test test test
    test test
    $
    $ sed -r 's/(([^|]+\|){2})(([^|]+\|){3})/\1/' file
    >A|B|F
    test test test
    test test
    >A|B|F
    test test test
    test
    >gene_8|GeneMark.hmm|4771TS28_contig03869
    test test test
    test test
    

    【讨论】:

      【解决方案3】:

      sed 工作正常:

      $ cat 1
      >A|B|C|D|E|F
      test test test
      test test
      >A|B|C|D|E|F
      test test test
      test
      $ sed 's/C|D|E|//' 1
      >A|B|F
      test test test
      test test
      >A|B|F
      test test test
      test
      

      更新

      $ sed  's/\([^|]|[^|]|\).*|/\1/' 1
      >A|B|F
      test test test
      test test
      >A|B|F
      test test test
      test
      

      【讨论】:

      • 也许我的问题不清楚。 A、B、C、D、E、F 是字符串。例如:&gt;gene_8|GeneMark.hmm|322_aa|+|3803|4771TS28_contig03869。我想从字符串中独立删除内容。
      【解决方案4】:

      也许 适合这个

      awk --re-interval -F'|'\
            'NF > 4{$0=gensub(/^(([^|]*\|){2})([^|]*\|){3}(.*)$/, "\\1\\4", -1)};
            {print}' file
      

      【讨论】:

      • 仅供参考,在较旧的 gawk 版本中您只需要 --re-interval,这是最近 gawk 的默认行为(不,我不知道什么时候改变了,但已经有一段时间了)。此外,您不需要设置 OFS,因为您没有重新编译记录,您可以只执行 $0=gensub(...) 并丢失中间变量 z
      • @EdMorton,好点,并入。我将--re-interval 留在那里,因为我的GNU 版本awk (3.1.8) 似乎需要它
      【解决方案5】:

      应该这样做。 -i 选项指定要就地编辑文件。

      perl -i.bak -pe 's/\|[CDE]//g' file
      

      或使用 sed

      sed -i.bak -re 's/\|[CDE]//g' file
      

      【讨论】:

        【解决方案6】:

        awk 也可以正常工作:

        awk '{sub(/C\|D\|E\|/,"")}1' file
        >A|B|F
        test test test
        test test
        >A|B|F
        test test test
        test 
        

        【讨论】:

          猜你喜欢
          • 2012-07-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-05
          • 2014-06-21
          • 2012-05-11
          相关资源
          最近更新 更多