我有一个输入文件(制表符分隔),其中包含 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