对于给定文件,使用 AWK 打印包含特定模式的列

对于给定文件,使用 AWK 打印包含特定模式的列

我有一个输入文件(制表符分隔),其中包含 200 多列(仅显示几列)。

col1     col2        col3          col4               col5 
ID       GPD1431     GPD1632       GPD1253            GPD2353
Group    GDS_Treated GDS_Untreated GDS_paired_Treated GDS_paired_Untreated 
Measure1 7.6         8.2           9.3                4.2
Measure2 0.32        0.56          0.343              0.423

我想要做的是对该数据文件进行子集化,以便我只获得组描述未处理样本或第一列的列。我希望输出文件也是制表符分隔的文件。就像这样:

col1     col3          col5 
ID       GPD1632       GPD2353
Group    GDS_Untreated GDS_paired_Untreated 
Measure1 8.2           4.2
Measure2 0.56          0.423

到目前为止,我所拥有的是这样的:

awk -F '\t' '{for(i=1; i<=NF; i++) {if($i ~ /Untreated|untreated/ || i==1) col_array[i]=i}} END {for (val in col_array) {print col_array[val]}}' file > columns_to_print.txt

该输出的结果是:

1
3
7
9
12
43
...
203

打印出 col_array 的内容,根据快速目视检查,这些数字似乎与正确的列号匹配。所以,这似乎是一个好的开始。但我对如何使用此信息在制表符分隔文件中打印出我想要的列感到困惑。

我已经尝试过了awk 'NR==FNR{columns[$1]=$1;next}{for(i=1; i<=NF; i++){if(columns[i]>1)print $i}}' columns_to_print.txt file,但这似乎没有打印出正确的列(并且打印出的内容经过格式化,使得所有内容都在一列中。)

感谢您的帮助。

答案1

这是awk此任务的脚本:

awk -F '\t' 'BEGIN {cols[1]}
    pass == 1 && $1 == "Group" {
        for (i=2;i<=NF;i++) if ($i ~ /[Uu]ntreated$/) cols[i]
        nextfile
    }
    pass == 2 {
        rec = ""
        for (i=1;i<=NF;i++) {
            if (i in cols) rec = (rec ? rec FS $i : $i)
        }
        print rec
    }' pass=1 file pass=2 file

首先,我们搜索以“Group”开头的行,并且对于该行,我们存储与我们的模式匹配的字段的列号。我们立即退出第一个解析nextfile

在第二遍中,我们仅打印存储在 中的列cols。循环所有字段并构造要打印到变量中的行rec。也是一个标准条件表达式正在这里使用。

测试输出:

col1      col3           col5
ID        GPD1632        GPD2353
Group     GDS_Untreated  GDS_paired_Untreated
Measure1  8.2            4.2
Measure2  0.56           0.423

相关内容