如何在 AWK 中一次删除多个列和字段分隔符?
Posted
技术标签:
【中文标题】如何在 AWK 中一次删除多个列和字段分隔符?【英文标题】:How to remove several columns and the field separators at once in AWK? 【发布时间】:2012-11-01 22:46:15 【问题描述】:我有一个包含数千列的大文件。我想在 Bash 中使用 AWK 一次删除一些特定的列和字段分隔符。
我可以用这个 oneliner 一次删除一列(将删除第 3 列及其对应的字段分隔符):
awk -vkf=3 -vFS="\t" -vOFS="\t" 'for(i=kf; i<NF;i++) $i=$(i+1);; NF--; print' < Big_File
但是,我想一次删除几列...有人可以帮我解决这个问题吗?
【问题讨论】:
不,不是。在这里您选择特定列,而不是区间内的列... 我不同意。在上述两个问题中,都会出现删除范围和列列表的答案。 对于 AWK,我真的找不到... 我的投票太仓促了。事实上,这两个问题都有关于如何使用cut
的答案,但不是awk
。投票重新开放。
【参考方案1】:
这是卡米尔想法的一个实现:
awk -v remove="3,8,5" '
BEGIN
OFS=FS="\t"
split(remove,a,",")
for (i in a) b[a[i]]=1
j=1
for (i=1;i<=NF;++i)
if (!(i in b))
$j=$i
++j
NF=j-1
print
'
【讨论】:
谢谢,但是那个脚本改变了字段分隔符,我想继续使用“tab”作为分隔符,知道吗? 不在 -v 和变量赋值之间放置空格会使您的解决方案不必要地特定于 gawk。此外,如果您要将 FS 和 OFS 设置为相同的值,则只需在 BEGIN 部分中使用 FS=OFS="\t" 会更简洁。【参考方案2】:这样的事情应该可以工作:
awk -F'\t' -v remove='3|8|5' '
rec=ofs=""
for (i=1;i<=NF;i++)
if (i !~ "^(" remove ")$" )
rec = rec ofs $i
ofs = FS
print rec
' file
【讨论】:
【参考方案3】:如果您可以使用cut
而不是awk
,则使用cut
会更容易:
例如这会从文件中获得第 1,3 列和第 50 列:
cut -f1,3,50- file
【讨论】:
【参考方案4】:您可以将要从 shell 中删除的列列表传递给 awk
,如下所示:
awk -vkf="3,5,11" ...
然后在awk
程序中解析成数组:
split(kf,kf_array,",")
然后遍历所有列并测试每个特定列是否在 kf_array 中并可能跳过它
另一种可能性是多次致电您的 oneliner :-)
【讨论】:
以上是关于如何在 AWK 中一次删除多个列和字段分隔符?的主要内容,如果未能解决你的问题,请参考以下文章