csv Bash -从tsv文件中提取一个列,该列的头与给定模式匹配

hi3rlvi2  于 2023-04-18  发布在  其他
关注(0)|答案(3)|浏览(394)

我有一个名为dataTypeA.txt的制表符分隔的文件。它看起来像这样:

Probe_ID    GSM24652    GSM24653    GSM24654    GSM24655    GSM24656    GSM24657
1007_s_at   1149.82818866431    1156.14191288693    743.515922643437    1219.55564561635    1291.68030259557    1110.83793199643
1053_at 253.507372571459    150.907554200493    181.107054946649    99.0610660103702    147.953428467212    178.841519788697
117_at  157.176825094869    147.807257232552    162.11169957066 248.732378039521    176.808414979907    112.885784025819
121_at  1629.87514240262    1458.34809770171    1397.36209234134    1601.83045996129    1777.53949459116    1256.89054921471
1255_g_at   91.9622298972477    29.644137111864 61.3949774595639    41.2554576367652    78.4403716513328    66.5624213750532
1294_at 313.633291641829    305.907304474766    218.567756319376    335.301256439494    337.349552407502    316.760658896597
1316_at 195.799277107983    163.176402437481    111.887056644528    194.008323756222    211.992656497053    135.013920706472
1320_at 34.5168433158599    19.7928225262233    21.7147425051394    25.3213322300348    22.4410631949167    29.6960283168278
1405_i_at   74.938724593443 24.1084307838881    24.8088845994911    113.28326338746 74.6406975005947    70.016519414531
1431_at 88.5010900723741    21.0652011409692    84.8954961447585    110.017339630928    84.1264201735067    49.8556999547353
1438_at 26.0276274326623    45.5977459152141    31.8633816890024    38.568939176828 43.7048363737468    28.5759163094148
1487_at 1936.80799770498    2049.19167519573    1902.85054762899    2079.84030768241    2088.91036902825    1879.84684705068
1494_f_at   358.11266607978 271.309665853292    340.738488775022    477.953251687206    388.441738062896    329.43505750512
1598_g_at   2908.90515715761    4319.04621682741    2405.62061966298    3450.85255814957    2573.97860992156    2791.38660060659
160020_at   416.089910909237    327.353902186303    385.030831004533    385.199279534446    256.512900212781    217.754025190117
1729_at 43.1079499314469    114.654670657195    133.191500889286    86.4106614983387    122.099426341898    218.536976034472
177_at  75.9653827137444    27.4348937420347    16.5837374743166    50.6758325717831    58.7568500760629    18.8061888366161
1773_at 31.1717741953018    158.225161489953    161.976679771553    139.173486349393    218.572194156366    103.916119454
179_at  1613.72113870554    1563.35465407698    1725.1817757679 1694.82209331327    1535.8108561345 1650.09670894426

假设我有一个变量col="GSM24655",我想从dataTypeA.txt中提取对应于这个列名的列。
另外,我想把它放在一个函数中,我可以给予它一个文件(即dataTypeA.txt)和一个列(即GSM24655),它会返回该列。我不是很精通Bash,所以我一直有一些麻烦。我很感激帮助。

twh00eeo

twh00eeo1#

下面使用awk的脚本可用于实现该目标。

col="GSM24655"; 
awk -v column_val="$col" '{ if (NR==1) {val=-1; for(i=1;i<=NF;i++) { if ($i == column_val) {val=i;}}} if(val != -1) print $val} ' dataTypeA.txt

工作:最初,col的值使用-v column_val="$col"传递到awk脚本。然后找出列号。(当NR==1,即第一行时,它迭代所有字段(for(i=1;i<=NF;i++),awk变量NF包含列数),然后比较column_val的值(if ($i == column_val)),当找到匹配时,找到并存储相应的列号(val=i))。之后,从下一行开始,打印该列中的值(print $val)。
如果将下面的代码复制到一个名为find_column.sh的文件中,你可以调用sh find_column.sh GSM24655 dataTypeA.txt来显示具有第一个参数值的列(GSM24655)在名为第二个参数的文件中(dataTypeA.txt)。$1$2是位置参数。column=$1file=$2行将输入值分配给变量。

column=$1;
file=$2; 
awk -v column_val="$column" '{ if (NR==1) {val=-1; for(i=1;i<=NF;i++) { if ($i == column_val) {val=i;}}} if(val != -1) print $val} ' $file
0g0grzrc

0g0grzrc2#

我会使用以下方法,它快速而简单。
在您的脚本中,您将获得文件名,假设为$1,word为$2。
然后,在我的for each中,我使用了整个标题,但你可以只添加一个head -1 $1,在IF中,$2,这将输出列名。

c=0;
for each in `echo "Probe_ID    GSM24652    GSM24653    GSM24654    GSM24655    GSM24656    GSM24657"`;do if [[ $each == "Probe_ID" ]];then 
echo $c;
col=$c; 
else c=$(( c + 1 )); 
fi;
done

在此之后,您只需执行cat $1| cut -d$'\t' -f$col

kx5bkwkv

kx5bkwkv3#

这也适用于按指定顺序打印多列:
tcut(){ awk -F\\t 'NR==FNR{a[NR]=$0;next}FNR==1{for(i=1;i<=NF;i++)b[$i]=i}{for(i in a)printf"%s"(i==length(a)?RS:FS),$(b[a[i]])}' <(printf %s\\n "$@") -;};tcut GSM24655 Probe_ID<input.tsv
或者另一个选项是csvtk -t cut -fGSM24655,Probe_ID input.tsv-t标志使用tab作为字段分隔符,但它不会禁用双引号的CSV样式处理。-l标志(--lazy-quotes)允许将未转义的双引号作为数据的一部分,但它仍然在包含双引号的字段周围打印双引号对,比如aa"aa被改为""aa"aa""-l也不会禁用删除CSV中不需要引号的字段周围的双引号,比如"bb"被改为bb

相关问题