在awk中删除第一列,保留剩余行不变

7

我正在尝试使用awk删除文本文件中的前三个字段。删除前三个字段很容易。但awk会破坏行的其余部分:分隔符从制表符更改为空格。

以下是我的尝试:

head pivot.threeb.tsv | awk 'BEGIN {IFS="\t"} {$1=$2=$3=""; print }' 

前三列已经被正确删除了。问题是输出结果中第四列、第五列和第六列之间的制表符被转换成了空格。

更新:这个问题被标记为重复的另一个问题创建时间晚于此问题,请查看日期。


1
awk 中没有名为 "IFS" 的变量。shell 有 IFS,awk 有 FS。 - Ed Morton
可能是重复的问题:使用awk从第n列打印到最后一列 - Ciro Santilli OurBigBook.com
您好,当前的共识是通过“质量”来关闭问题:http://meta.stackexchange.com/questions/147643/should-i-vote-to-close-a-duplicate-question-even-though-its-much-newer-and-ha。由于“质量”不可测量,我只看赞数。;-) 很可能最终取决于哪个问题的标题命中了最佳的新手 Google 关键字。 - Ciro Santilli OurBigBook.com
请设身处地地替我想一想。我之前提出了一个问题,但却得到了一个关闭的回答。而那个创建了类似问题的人却可以保留它。你会如何看待这种情况? - WestCoastProjects
4个回答

6

首先,正如ED所评论的那样,您需要在awk中使用FS作为字段分隔符。 由于您没有定义OFS,所以tab在输出中变成了space

awk 'BEGIN{FS=OFS="\t"}{$1=$2=$3="";print}' file

这将删除前三个字段,并保留其余文本 "不变"(您将看到前面的三个制表符)。输出中的 <tab> 也会被保留。
awk 'BEGIN{FS=OFS="\t"}{print $4,$5,$6}' file

将无需前导空格/制表符输出。但是如果您有500个列,您必须在循环中执行此操作,或使用sub函数或考虑其他工具(例如cut)。


5
实际上,这可以通过一个非常简单的 cut 命令来完成,如下所示:
cut -f4- inFile

我希望它不是被缓存的。 - Nakilon

3

如果您不想改变字段分隔符,请使用sed删除前三列:

sed -r 's/(\S+\s+){3}//' file

为了将更改存储回文件,您可以使用-i选项:
sed -ri 's/(\S+\s+){3}//' file

\S\s都是PCRE的特性。不能保证sed支持它们;POSIX标准仅保证BRE具有非常少量的扩展--请参见https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html#tag_20_116_13_02 - Charles Duffy
编写\s的可移植方式是[[:space:]],编写\S的可移植方式是[^[:space:]] - Charles Duffy

0
awk '{for (i=4; i<NF; i++) printf $i " "; print $NF}'

如果最后一列包含名称中的双空格,则此代码将失败。 - meso_2600
如果任何一行的字段少于四个,这将无法产生预期的输出。(它会打印它们中的最后一个而不是删除所有。)相反,您可以使用:awk '{for (i=4; i<=NF; i++) printf $i " "; printf "\n"}'或添加一些额外的逻辑来防止尾随空格。 - Wildcard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接