正则表达式用 SED/AWK 替换特定列

Regex replace on specific column with SED/AWK

我有这样的数据(制表符分隔):

Organ K     ClustNo Analysis
LN    K200  C12     Gene Ontology
LN    K200  C116    Gene Ontology
CN    K200  C2      Gene Ontology

我想要做的是删除 第 3 列 上每一行的 C,除了 header 行:

Organ K     ClustNo Analysis
LN    K200  12      Gene Ontology
LN    K200  116     Gene Ontology
CN    K200  2       Gene Ontology

这不行,因为它会影响其他列和 header 行:

sed 's/C//'

正确的做法是什么?

使用 awk

awk 是一个很好的工具:

$ awk -F'\t' -v OFS='\t' 'NR>=2{sub(/^C/, "", )} 1' file
Organ   K       ClustNo Analysis
LN      K200    12      Gene Ontology
LN      K200    116     Gene Ontology
CN      K200    2       Gene Ontology

工作原理

  • -F'\t'

    在输入时使用制表符作为字段分隔符。

  • -v OFS='\t'

    使用制表符作为输出的字段分隔符

  • NR>=2 {sub(/^C/, "", )}

    仅针对第一行之后的行从字段 3 中删除初始 C

  • 1

    这是 awk 的神秘 shorthand 打印行。

使用 sed

$ sed -r '2,$ s/(([^\t]+\t+){2})C//' file
Organ   K       ClustNo Analysis
LN      K200    12      Gene Ontology
LN      K200    116     Gene Ontology
CN      K200    2       Gene Ontology
  • -r

    使用扩展的正则表达式。 (在 Mac OSX 或其他 BSD 平台上,使用 -E 代替。)

  • 2,$ s/(([^\t]+\t){2})C//

    此替换仅适用于从 2 到文件末尾的行。

    (([^\t]+\t){2}) 匹配前两个制表符分隔的列。这假定只有一个选项卡分隔每一列。因为正则表达式包含在括号中,所以它匹配的内容稍后将作为 </code>.</p> 提供 <p><code>C 这场比赛 C.

    </code> 只用前两列替换匹配的文本,而不是 <code>C..