如何基于if语句为新文件选择数据列?

时间:2019-01-23 11:03:15

标签: shell unix if-statement awk

我正在从原始大数据集中子集数据。 我设法从这个原始数据中选择了一个新文件所需的列数,但是随后尝试基于if语句进行进一步选择(要求新文件的第28列仅包含<= 5000行)代码似乎并不能保持制表符字段分隔,而且还从我的数据中删除了标题行。我是使用Linux的新手,因此可以接受任何指导。

awk 'BEGIN{FS="\t"} { for(i=125; i<=NF; ++i) printf $i""FS; print ""}' Bigfile.txt> Smallfile.txt

awk 'BEGIN{FS="\t"} {if($28<=5000) print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$28}' Smallfile.txt > Smallfile1.txt

第一行awk行工作正常,并从原始数据集中选择了我想要的28列。第二行然后不让我进一步细分。我试过删除BEGIN,然后添加;在某些地方,并使用-F“ \ t”代替{FS =“ \ t”}

2 个答案:

答案 0 :(得分:1)

能否请您尝试一次。由于您主要担心的是您的输出不是以TAB分隔格式显示的,因此在OFS="\t"部分中设置BEGIN的值应该可以解决这一问题。

现在第二个问题是,您需要打印我放置了FNR==1{print;next}条件的标头,应该注意这一点(FNR==1表示它正在检查行号是否为1,然后执行以下操作然后print将打印第一行,nextawk的开箱即用功能,它将跳过此处的所有其他语句)。由于您还没有显示样本,所以我无法对其进行测试。

awk 'BEGIN{FS=OFS="\t"} FNR==1{print;next} {if($28<=5000) print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$28}' Smallfile.txt > Smallfile1.txt

答案 1 :(得分:1)

您尝试执行的任务显然可以在单个awk脚本中完成。

第一个awk脚本从第125列中选择所有列。您的第二个awk脚本根据第28列的值进行辅助选择。

这也等效:

awk 'BEGIN{FS=OFS="\t"}
     (FNR==1) || ($(125+28-1) <= 5000) {
         for(i=125;i<=NF;++i) printf (i==125?"":OFS) $i; printf ORS
     }' BigFile > SmallFile1

之所以可行,是因为awk与pattern { action }对一起工作,说明是否满足pattern,请执行action。这里的模式是(FNR==1) || ($(125+28-1) <= 5000),表示如果我们正在处理文件pattern或((FNR==1))的第一条记录,则第28列大于或等于|| 5000 ($(125+28-1) <= 5000)