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

nev*_*int 3 unix linux awk sed

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

Organ K     ClustNo Analysis
LN    K200  C12     Gene Ontology
LN    K200  C116    Gene Ontology
CN    K200  C2      Gene Ontology
Run Code Online (Sandbox Code Playgroud)

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

Organ K     ClustNo Analysis
LN    K200  12      Gene Ontology
LN    K200  116     Gene Ontology
CN    K200  2       Gene Ontology
Run Code Online (Sandbox Code Playgroud)

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

sed 's/C//'
Run Code Online (Sandbox Code Playgroud)

什么是正确的方法呢?

Joh*_*024 10

使用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
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

  • -F'\t'

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

  • -v OFS='\t'

    使用tab作为输出上的字段分隔符

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

    C仅在第一行之后的行中从字段3中删除初始值.

  • 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
Run Code Online (Sandbox Code Playgroud)
  • -r

    使用扩展正则表达式.(在Mac OSX或其他BSD平台上,请-E改用.)

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

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

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

    C这场比赛C.

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