根据标题功能提取文件列

时间:2018-10-05 03:58:11

标签: shell awk sed

我有一个较大的csv矩阵文件(input.csv),格式如下:

Patient,sample 66_pos_LC/MS Pos_con,sample 57_net_LC/MS Neg_dis,sample 1_LC/MS Polar_con,sample 3_LC/MS Neg_net
xx,2.5,-7.8,2.5,3.6
ab 1,5.4,3,0.3
yy,43,33,77,55

根据文件的第一行,我想基于LC / MS功能拆分文件内容。也就是说,如果我要所有LC / MS Neg,输出文件将如下所示:

output1.csv

Patient,sample 57_net_LC/MS Neg_dis,sample 3_LC/MS Neg_net
xx,-7.8,3.6
ab,5.4,0.3
yy,33,55

为此,我使用:

head -n 1 input.csv | tr ',' '\n' | cat -n | grep 'LC/MS Neg'

这给出了我应该查看的列号(在本例中为3和5);要获得以上输出,我使用:

cut -d, -f1,3,5 input.csv > output1.csv

尽管它给了我想要的输出,但是我发现这一次要提取很多列会很复杂。

我将非常感谢一些awk / sed解决方案。

谢谢。

2 个答案:

答案 0 :(得分:2)

$ cat tst.awk
BEGIN { FS=OFS="," }
NR==1 {
    f[++numFlds] = 1
    for (i=2; i<=NF; i++) {
        if ($i ~ sel) {
            f[++numFlds] = i
        }
    }
}
{
    for (i=1; i<=numFlds; i++) {
        printf "%s%s", $(f[i]), (i<numFlds ? OFS : ORS)
    }
}

$ awk -v sel=Neg -f tst.awk file
Patient,sample 57_net_LC/MS Neg_dis,sample 3_LC/MS Neg_net
xx,-7.8,3.6
ab 1,3,
yy,33,55

$ awk -v sel=Pos -f tst.awk file
Patient,sample 66_pos_LC/MS Pos_con
xx,2.5
ab 1,5.4
yy,43

$ awk -v sel=Polar -f tst.awk file
Patient,sample 1_LC/MS Polar_con
xx,2.5
ab 1,0.3
yy,77

$ awk -v sel='Pos|Neg' -f tst.awk file
Patient,sample 66_pos_LC/MS Pos_con,sample 57_net_LC/MS Neg_dis,sample 3_LC/MS Neg_net
xx,2.5,-7.8,3.6
ab 1,5.4,3,
yy,43,33,55

答案 1 :(得分:0)

ActionFilter
  • 将输入和输出字段分隔符设置为$ cat get_cols.awk BEGIN{ FS=OFS="," } NR==1 { i = 1 idx[i++] = 1 for(j=2; j<=NF; j++) if($j ~ /LC\/MS Neg/) idx[i++] = j } { for(k=1; k<i; k++) printf "%s", k==1 ? $idx[k] : OFS $idx[k] print "" }
  • 使用数组,保存我们需要打印的索引
    • 始终需要第一列
    • 要获取其余的内容,请遍历标头字段并查看哪些符合条件
  • 然后打印字段

运行为:

idx


$ awk -f get_cols.awk ip.txt Patient,sample 57_net_LC/MS Neg_dis,sample 3_LC/MS Neg_net xx,-7.8,3.6 ab,5.4,0.3 yy,33,55

的概念相同
perl