删除列中字符之前的所有内容

Eri*_*lez 4 sed awk text-processing

我有一张这样的桌子

start end chr
  1   10  H300Chr01
  10  50  H500Chr02
Run Code Online (Sandbox Code Playgroud)

我想替换第 3 列中“Chr”之前的所有内容。

我想要的输出是

start end chr
  1   10  Chr01
  10  50  Chr02
Run Code Online (Sandbox Code Playgroud)

我知道sed可以做这样的事情:

sed 's/^.*Chr/Chr/' table.txt
Run Code Online (Sandbox Code Playgroud)

您能否告诉我如何针对特定列或几列实现此目的?

ter*_*don 6

对于一些(所有?)awk实现,当然是 GNUawkmawk我在 Arch Linux 系统上的实现,您可以将字段分隔符设置为正则表达式,这使得 awk 保留文件的原始分隔符。为了显示:

$ awk '{$1=$1;print}' file
start end chr
1 10 H300Chr01
10 50 H500Chr02

$ awk -F'[ ]' '{$1=$1;print}' file
start end chr
  1   10  H300Chr01
  10  50  H500Chr02
Run Code Online (Sandbox Code Playgroud)

考虑到这一点,我们可以更改最后一个(我说最后一个而不是第三个,因为这种方法会重新绘制线条,并且编号会根据空格数而变化)字段,而无需更改间距,如下所示:

$ awk -F'[ ]' '{sub(/.*Chr/,"Chr",$NF);}1' file
start end chr
  1   10  Chr01
  10  50  Chr02
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用perl

$ perl -pne 's/(\s*\S+\s+\S+\s+)\S+(Chr)/$1$2/;' file 
start end chr
  1   10  Chr01
  10  50  Chr02
Run Code Online (Sandbox Code Playgroud)

或者,为了确保仅匹配Chr第三个字段中第一次出现的 ,以防出现多个:

perl -pe 's/(\s*\S+\s+\S+\s+)\S+?(Chr)/$1$2/;' file 
Run Code Online (Sandbox Code Playgroud)

  • @thanasisp是的,这就是为什么我在答案中指出它改变了字段的数量以及为什么我使用`$NF`以及为什么我还提供了一个perl解决方案。不幸的是,定义“OFS”和“column -t”都不起作用,因为我们有前导空格 (2认同)