6

我有一个包含数千列的大文件。我想在 Bash 中使用 AWK 一次删除一些特定的列和字段分隔符。

我可以使用这个 oneliner 一次删除一列(将删除第 3 列及其相应的字段分隔符):

awk -vkf=3 -vFS="\t" -vOFS="\t" '{for(i=kf; i<NF;i++){ $i=$(i+1);}; NF--; print}' < Big_File

但是,我想一次删除几列...有人可以帮我解决这个问题吗?

4

4 回答 4

5

您可以将要从 shell 中删除的列列表传递给awk这样的:

awk -vkf="3,5,11" ...

然后在awk程序中将其解析为数组:

split(kf,kf_array,",")

然后遍历所有列并测试每个特定列是否在 kf_array 中并可能跳过它

另一种可能性是多次致电您的oneliner :-)

于 2012-11-13T14:01:13.163 回答
4

这是卡米尔想法的实现:

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
  }
'
于 2012-11-13T14:19:30.367 回答
3

如果您可以使用cut代替awk,则使用以下内容更容易cut

例如,这会从文件中获取第 1,3 列和第 50 列:

cut -f1,3,50- file

于 2012-11-13T14:41:46.927 回答
0

像这样的东西应该工作:

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
于 2012-11-14T13:39:55.090 回答