Linux / bash / awk读取部分文件名作为变量

时间:2014-07-09 01:52:27

标签: python linux bash csv awk

我们写了一个awk one liner来将输入csv文件(Assay_51003_target_pairs.csv)拆分成多个文件。对于任何行,如果它们的列1等于另一列列1,则列2等于另一列2等,这些行将被分类为新文件。将使用列值命名新文件。

这是一个班轮

awk -F "," 'NF>1 && NR>1 && $1==$1 && $2==$2 && $9==$9 && $10==$10{print $0 >> ("Assay_"$1"_target_"$3"_assay_" $9 "_bcassay_" $10 "_bcalt_assay.csv");close("Assay_"$1"_target_"$3"_assay_" $9 "_bcassay_" $10 "_bcalt_assay.csv")}' Assay_51003_target_pairs.csv

这将生成以下示例输出(Assay_ $ 1_target_ $ 3_assay_ $ 9_bcassay_ $ 10_bcalt_assay.csv):

Assay_51003_target_1645_assay_7777_bcassay_8888_bcalt_assay.csv

51003,666666,1645,11145,EC50,,0.2,uM,7777,8888,IC50,,1,uM,,3,2.0555,3011-02-0100:00:00,1911-04-1100:00:00,Cell,Biochemical
51003,666666,1645,1680,EC50,<,0.1,uM,7777,8888,IC50,,1,uM,,2,2.8579,3004-06-0300:00:00,3000-04-1100:00:00,Cell,Biochemical

Assay_51003_target_1645_assay_7777_bcassay_9999_bcalt_assay.csv

51003,666666,1645,11145,EC50,,0.2,uM,7777,9999,IC50,,1,uM,,3,2.0555,3011-02-0100:00:00,1911-04-1100:00:00,Cell,Biochemical
51003,666666,1645,1680,EC50,<,0.1,uM,7777,9999,IC50,,1,uM,,2,2.8579,3004-06-0300:00:00,3000-04-1100:00:00,Cell,Biochemical

Assay_51003_target_1688_assay_7777_bcassay_9999_bcalt_assay.csv

51003,666666,1688,11145,EC50,,0.2,uM,7777,9999,IC50,,1,uM,,3,2.0555,3011-02-0100:00:00,1911-04-1100:00:00,Cell,Biochemical
51003,666666,1688,1680,EC50,<,0.1,uM,7777,9999,IC50,,1,uM,,2,2.8579,3004-06-0300:00:00,3000-04-1100:00:00,Cell,Biochemical

稍后我们想做,例如,

awk -F, -f max_min.awk Assay_51003_target_1645_assay_7777_bcassay_8888_bcalt_assay.csv

awk -F, -f max_min.awk Assay_51003_target_1645_assay_7777_bcassay_9999_bcalt_assay.csv

awk -F, -f max_min.awk Assay_51003_target_1688_assay_7777_bcassay_9999_bcalt_assay.csv

#################################################

for b in 1645 1688

do

     for c in 8888 9999

     do

     awk -F, -f max_min.awk Assay_51003_target_$b_assay_7777_bcassay_$c_bcalt_assay.csv

     done

done  

但是,我们不知道是否有任何方法为后续工作编写循环,因为outfile名称是“随机”的。我们可以知道linux / bash是否有办法将部分文件名解析为循环变量(例如将1645和1688分解为b和8888&amp; 9999分解为c)?

2 个答案:

答案 0 :(得分:1)

使用Bash,应该非常容易地授予值始终是数字:

shopt -s nullglob

FILES=(Assay_*_target_*_assay_*_bcassay_*_bcalt_assay.csv)  ## No need to do +([[:digit:]]). The difference is unlikely.
for FILE in "${FILES[@]}"; do
    IFS=_ read -a A <<< "$FILE"
    # Do something with ${A[1]} ${A[3]} ${A[5]} and ${A[7]}
    ...

    # Or

    IFS=_ read __ A __ B __ C __ D __ <<< "$FILE"
    # Do something with $A $B $C and $D
    ...
done

答案 1 :(得分:0)

询问$1 == $1等是否毫无意义,因为它永远都是真的。以下代码是等效的:

awk -F, '
  NF > 1 && NR > 1 {
    f = "Assay_" $1 "_target_" $3 "_assay_" $9 \
        "_bcassay_" $10 "_bcalt_assay.csv"
    print >> f;
    close(f)
}' Assay_51003_target_pairs.csv

这样做的原因是,如果文件名构造中使用的字段匹配,则附加相同的文件。但是我想知道,如果你在描述中提到$3,那么使用$2代替$2是否属于错误。

无论如何,你在做什么似乎很奇怪。如果你可以直截了当地描述你实际想要完成的事情,那么可能会采用完全不同的方式。