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

时间:2015-03-17 04:07:41

标签: linux unix awk sed

我的数据看起来像这样(TAB分隔):

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

我想要做的是删除第3列上每一行的C,但标题行除外:

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

这样做不会,因为它会影响其他列和标题行:

sed 's/C//'

这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:8)

使用awk

awk是一个很好的工具:

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

如何运作

  • -F'\t'

    使用tab作为输入的字段分隔符。

  • -v OFS='\t'

    使用tab作为输出

  • 上的字段分隔符
  • NR>=2 {sub(/^C/, "", $3)}

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

  • 1

    这是awk用于打印线的神秘简写。

使用sed

$ sed -r '2,$ s/(([^\t]+\t+){2})C/\1/' 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/\1/

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

    (([^\t]+\t){2})匹配前两个以制表符分隔的列。这假设只有一个选项卡分隔每列。由于正则表达式包含在parens中,因此匹配的内容稍后将以\1的形式提供。

    C此匹配C

    \1仅使用前两列替换匹配的文字,而不是C ..