【问题标题】:Remove columns when line matches a condition当行匹配条件时删除列
【发布时间】:2015-06-06 12:50:19
【问题描述】:

我正在尝试从文本文件中删除与字符串匹配的行中的某些列,但其余行保持不变。

假设我有一个文件(实际上有数千行)

10 12 a
USA John TGCAGG
USA John TGCATG
5 2 b
CAN Tom TGCACG
CAN Tom TGCAAC
....

我想创建一个新文件,删除包含 TGCA 的行中的第二列,但保留所有其他行不变。我想看看:

10 12 a
USA TGCAGG
USA TGCATG
5 2 b
CAN TGCACG
CAN TGCAAC

我可以修改在匹配的行上打印哪些列,使用正则表达式启动 awk 或 sed,但我无法打印其他行(未修改)或保留这些行的顺序。

我需要在 awk 中使用 if 语句吗?尝试使用下一个,但我认为我没有这个权利。

【问题讨论】:

    标签: regex bash awk sed pattern-matching


    【解决方案1】:

    我会说:

    $ awk '/TGCA/ {$2=$3; NF--} 1' file
    10 12 a
    USA TGCAGG
    USA TGCATG
    5 2 b
    CAN TGCACG
    CAN TGCAAC
    

    即:当该行包含TGCA时,将第2列替换为第3列,并减少字段数。即删除第 2 列。

    【讨论】:

    • 我不太了解这里如何使用 NF 或如何设置所需的字段数...如果有 4 列并且我想保留 3 和 4 怎么办?或者假设我想保留第 1 列、第 3 列和第 4 列(但不是第 2 列)?有没有更通用的方法来做到这一点(或解释代码)而不减少字段?
    • 在 awk 中删除一列是相当棘手的。为了防止出现尾随空格,我会选择这样的东西:how to remove the first two columns in a file using shell (awk, sed, whatever)
    • 因此,如果您能负担得起减少NF 的费用就可以了。如果它必须更复杂,我仍然会做一些列移动,最后还是减少NF。
    • 好的。这将在匹配 TGCA 的行上打印字段 3 和 4:awk '/TGCA/{print substr($0, index($0, $3))}'。但是,只打印那些行。知道如何获得其他线路吗? awk 例程末尾的 1 是重要的代码吗?
    • @LP_640 1 代表“真”,因此无论如何它都会打印该行。如果您已经打印了它,那么您可以使用 next: awk '/TGCA/{print substr($0, index($0, $3)); next} 1' 跳过它。
    【解决方案2】:

    使用 GNU sed:

    sed '/TGCA/ s/\s\+\S*//' filename
    

    这将从包含TGCA 的行中删除第一次出现的一个或多个空格,后跟任意数量的非空格——即第二列和它前面的空格。

    对于 BSD sed,这必须修改,因为它不理解 \s 或 \S(或 \+ - 有点痛苦)。在这种情况下,

    sed '/TGCA/ s/[[:space:]]\{1,\}[^[:space:]]*//' filename
    

    做同样的事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-13
      • 2020-08-06
      • 1970-01-01
      相关资源
      最近更新 更多