如何选择不相邻的多个列?

时间:2019-01-23 13:39:18

标签: unix awk

我有一个数据集,我试图从中选择前10列,并从中选择最后27列(从第125列开始到最后第152列)。

awk 'BEGIN{FS="\t"} { printf $1,$2,$3,$4,$5,$6,$7,$8,$9,$10; for(i=125; i<=NF; ++i) printf $i""FS; print ""}' Bigdata.txt > Smalldata.txt 

尝试这段代码后,它将为我提供前12列(及其数据)以及原始大数据文件中所有152列的所有标题。如何同时选择第1-10列和第125-152列以进入新文件?我是linux的新手,任何指导将不胜感激。

3 个答案:

答案 0 :(得分:2)

如果您已经知道cut的列数是完成此任务的工具,则不要重新发明轮子。

$ cut -f1-10,125-152 bigdata

tab是默认的分隔符。

如果您不知道列数,awk可以帮助您!

$ cut -f1-10,$(awk '{print NF-27"-"NF; exit}' file) file

awk将通过读取文件的第一行来打印结束范围。

答案 1 :(得分:1)

请问您是否尝试以下操作,因为未生产任何样品,因此无法对其进行测试。您无需手动编写1...10字段值,也可以为此使用循环。

awk 'BEGIN{FS=OFS="\t"}{for(i=1;i<=10;i++){printf("%s%s",$i,OFS)};for(i=(NF-27);i<=NF;i++){printf("%s%s",$i,i==NF?ORS:OFS)}}' Input_file > output_file

这里您也不必担心标题,因为我们只是在打印行,而没有专门用于行的逻辑,因此不需要为第一行左右添加任何特定条目。

编辑: :这里还有1点似乎意味着不同的列值(在不同的范围内)应该放在一行中(对于Input中的一行)就是这种情况,那么我上面的代码应该处理它,因为我正在打印空格作为其值的分隔符,并且仅在最后一个字段的值被打印时才打印一个新的,因此,Input_file字段中的每一行都将位于同一行(与Input_file的条目相同) )。

说明: 在此处添加详细说明。

awk '                                       ##Starting awk program here.
BEGIN{                                      ##Starting BEGIN section here, which will be executed before Input_file is getting read.
  FS=OFS="\t"                               ##Setting FS and OFS as TAB here.
}                                           ##Closing BEGIN section here for this awk code.
{                                           ##Starting a new BLOCK which will be executed when Input_file is being read.
  for(i=1;i<=10;i++){                       ##Running a for loop which will run 10 times from i=1 to i=10 value.
     printf("%s%s",$i,OFS)                  ##Printing value of specific field with OFS value.
  }                                         ##Closing for loop BLOCK here.
  for(i=(NF-27);i<=NF;i++){                 ##Starting a for loop which will run for 27 last fields only as per OP requirements.
     printf("%s%s",$i,i==NF?ORS:OFS)        ##Printing field value and checking condition i==NF, if field is last field of line print new line else print space.
  }                                         ##Closing block for, for loop now.
}' Input_file > output_file                 ##Mentioning Input_file name here, whose output is going into output_file.

答案 2 :(得分:1)

使用KISS principle

awk 'BEGIN{FS=OFS="\t"} 
     { c=""; for(i=1;i<=10;++i)     { printf c $i; c=OFS}
             for(i=NF-27;i<=NF;++i) { printf c $i       }
       printf ORS }' file