Reputation: 343
I am trying to change the headers from a multi fasta file using awk.
My file looks as follows:
>NS500106:288:HGHTHAFXY:1:11101:16650:2011:CTATAC;size=206083;
GTACAACCTCCAGGAAATCGTGCCCGGCAGCGTGTGGATGGAGAGGGACGTG
>NS500106:288:HGHTHAFXY:1:11101:1149:1903:CTATAC;size=19175;
CAGCGAGAGCGAGACGCAGCCGGTGAACCGCGTGGCGTACAACGTCGGCGGGCAGATGGCCACCAACAACCAGAGCTCCA
CCACTGCCCCCGCGACCGGCACGTACAACCTCCAGGAAATCGTGCCCGGCAGCGTGTGGATGGAGAGGGACGTG
I am using this command:
awk '/[^;]*/{print "Variant_" ++i; next} {print}' < input.fasta > output.fasta
Where, /[^;]*/
matches lines upto the first occurence of the semi colon and replaces matched part of the header with Variant_1, Variant_2 and so on.
The above command changes the entire header to Variant_1 and so on and also does not print the sequence lines.
How can I resolve this?
My desired output is as below:
Variant_1;size=206083;
GTACAACCTCCAGGAAATCGTGCCCGGCAGCGTGTGGATGGAGAGGGACGTG
Variant_2;size=19175;
CAGCGAGAGCGAGACGCAGCCGGTGAACCGCGTGGCGTACAACGTCGGCGGGCAGATGGCCACCAACAACCAGAGCTCCA
CCACTGCCCCCGCGACCGGCACGTACAACCTCCAGGAAATCGTGCCCGGCAGCGTGTGGATGGAGAGGGACGTG
Upvotes: 0
Views: 1358
Reputation: 8711
Check this Perl-one liner
$ cat callie.txt
>NS500106:288:HGHTHAFXY:1:11101:16650:2011:CTATAC;size=206083;
GTACAACCTCCAGGAAATCGTGCCCGGCAGCGTGTGGATGGAGAGGGACGTG
>NS500106:288:HGHTHAFXY:1:11101:1149:1903:CTATAC;size=19175;
CAGCGAGAGCGAGACGCAGCCGGTGAACCGCGTGGCGTACAACGTCGGCGGGCAGATGGCCACCAACAACCAGAGCTCCA
CCACTGCCCCCGCGACCGGCACGTACAACCTCCAGGAAATCGTGCCCGGCAGCGTGTGGATGGAGAGGGACGTG
$ perl -ne ' BEGIN {$x=1} { s/(.*?);/"Variant_${x};"/e and $x++ ; print }' callie.txt
Variant_1;size=206083;
GTACAACCTCCAGGAAATCGTGCCCGGCAGCGTGTGGATGGAGAGGGACGTG
Variant_2;size=19175;
CAGCGAGAGCGAGACGCAGCCGGTGAACCGCGTGGCGTACAACGTCGGCGGGCAGATGGCCACCAACAACCAGAGCTCCA
CCACTGCCCCCGCGACCGGCACGTACAACCTCCAGGAAATCGTGCCCGGCAGCGTGTGGATGGAGAGGGACGTG
$
Even shorter
$ perl -pe ' { s/(.*?);/sprintf("Variant_%d;",++$x)/e; }' callie.txt
Variant_1;size=206083;
GTACAACCTCCAGGAAATCGTGCCCGGCAGCGTGTGGATGGAGAGGGACGTG
Variant_2;size=19175;
CAGCGAGAGCGAGACGCAGCCGGTGAACCGCGTGGCGTACAACGTCGGCGGGCAGATGGCCACCAACAACCAGAGCTCCA
CCACTGCCCCCGCGACCGGCACGTACAACCTCCAGGAAATCGTGCCCGGCAGCGTGTGGATGGAGAGGGACGTG
$
Upvotes: 1
Reputation: 50750
Where, /[^;]*/ matches lines upto the first occurence of the semi colon and replaces matched part of the header with Variant_1, Variant_2 and so on.
No, this is wrong. It maches lines containing zero or more non-semicolon chars (e.g all lines) and prints Variant_n
where n
is line number. {print}
part is never reached.
Here is my approach:
$ awk 'BEGIN{FS=OFS=";"}NF>1{$1="Variant_"++i}1' file
Variant_1;size=206083;
GTACAACCTCCAGGAAATCGTGCCCGGCAGCGTGTGGATGGAGAGGGACGTG
Variant_2;size=19175;
CAGCGAGAGCGAGACGCAGCCGGTGAACCGCGTGGCGTACAACGTCGGCGGGCAGATGGCCACCAACAACCAGAGCTCCA
CCACTGCCCCCGCGACCGGCACGTACAACCTCCAGGAAATCGTGCCCGGCAGCGTGTGGATGGAGAGGGACGTG
Upvotes: 1
Reputation: 2091
You could try with:
>> awk '/>.*/{sub(/[^;]*/,"Variant_" ++i )}1' < input.fasta
Variant_1;size=206083;
GTACAACCTCCAGGAAATCGTGCCCGGCAGCGTGTGGATGGAGAGGGACGTG
Variant_2;size=19175;
CAGCGAGAGCGAGACGCAGCCGGTGAACCGCGTGGCGTACAACGTCGGCGGGCAGATGGCCACCAACAACCAGAGCTCCA
CCACTGCCCCCGCGACCGGCACGTACAACCTCCAGGAAATCGTGCCCGGCAGCGTGTGGATGGAGAGGGACGTG
What you tried deletes all the line, in this case, sub
solves that problem
Upvotes: 1