Reputation: 497
I've got a tab-delimited file called dataTypeA.txt
. It looks something like this:
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
Let's say I have a variable col="GSM24655"
. I want to extract the column from dataTypeA.txt that corresponds to this column name.
Additionally, I'd like to put this in a function, where I can just give it a file (i.e. dataTypeA.txt
), and a column (i.e. GSM24655
), and it'll return that column.
I'm not very proficient in Bash, so I've been having some trouble with this. I'd appreciate the help.
Upvotes: 0
Views: 919
Reputation: 8863
This also works for printing multiple columns in the specified order:
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
Or another option is csvtk -t cut -fGSM24655,Probe_ID input.tsv
. The -t
flag uses tab as field separator but it doesn't disable CSV-style treatment of double quotes. The -l
flag (--lazy-quotes
) allows including unescaped double quotes as part of the data, but it still prints pairs of double quotes around fields that contain double quotes, like aa"aa
is changed to ""aa"aa""
. -l
also doesn't disable removing double quotes around fields that don't need to be quoted in CSV, like "bb"
is changed to bb
.
Upvotes: 0
Reputation: 3530
Below script using awk
can be used to achieve the objective.
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
Working: Initially, value of col
is passed to awk
script using -v column_val="$col"
. Then the column number is find out. (when NR==1
, i.e the first row, it iterates through all the fields (for(i=1;i<=NF;i++)
, awk variable NF
contains the number of columns) and then compare the value of column_val
(if ($i == column_val)
), when a match is found the corresponding column number is found and stored ( val=i
)). After that, from next row onwards, the values in that column is printed (print $val
).
If you copy the below code into a file called say find_column.sh
, you can call sh find_column.sh GSM24655 dataTypeA.txt
to display the column having value of first parameter (GSM24655
) in the file named second parameter (dataTypeA.txt
). $1
and $2
are positional parameters. The lines column=$1
and file=$2
will assign the input values to the variables.
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
Upvotes: 2
Reputation: 1232
I would use the following, it is quick and easy.
In your script, you get the name of the file, let's say $1, and word, $2.
Then, in my for each I am using the whole header, but you can just add a head -1 $1
, and in the IF, the $2, this is going to output column name.
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
Right after this, you just do a cat $1| cut -d$'\t' -f$col
Upvotes: 1