1

I am new to shell scripting and I am trying to sequentially number the headers in a fasta file. The sequences in my fasta file look like this:

>Rodentia sp. 
MALWILLPLLALLILWGPDPAQAFVNQHLCGSHLVEALYILVCGERGFFYTPMSRREVED
PQVGQVELGAGPGAGSEQTLALEVARQARIVQQCTSGICSLYQENYCN

>Ovis aries
MALWTRLVPLLALLALWAPAPAHAFVNQHLCGSHLVEALYLVCGERGFFYTPKARREVEG
PQVGALELAGGPGAGGLEGPPQKRGIVEQCCAGVCSLYQLENYCN

I want to use awk in my shell script so that the headers are sequentially numbered, by inserting a number starting from 1 to n (where n is the number of sequences) after the ">", so that the sequences look like this:

> 1 Rodentia sp. 
MALWILLPLLALLILWGPDPAQAFVNQHLCGSHLVEALYILVCGERGFFYTPMSRREVED
PQVGQVELGAGPGAGSEQTLALEVARQARIVQQCTSGICSLYQENYCN

> 2 Ovis aries
MALWTRLVPLLALLALWAPAPAHAFVNQHLCGSHLVEALYLVCGERGFFYTPKARREVEG
PQVGALELAGGPGAGGLEGPPQKRGIVEQCCAGVCSLYQLENYCN

I tried using the sub function in awk, to do this, replacing every instance of ">" with "> [a number]".

awk '/>/{sub(">", "> ++i ")}1' file

However, I don't understand how to increment variables using the sub function in awk. I would like to know if there is a way to do this using the sub function. I understand how sub works, but I don't know how to declare the variable to be incremented properly.

I declared i to be 1 at the beginning of my shell script:

i=1

However, the output I get from the sub function is:

> ++$i Rodentia sp. 
> ++$i Ovis aries 

How can a declare a variable properly so that I can use the awk sub function to number the headers?

  • You are also new to this site, so please be so polite to read at least the tour. – Anthon Sep 30 '17 at 12:34
0

You were close, just take ++i outside of quoted substring "> ++i" to "> " ++i.

awk '/^>/{sub(">", "> "++i " ")}1' infile
| improve this answer | |
  • What is the reason for having to place ++i within its own set of quotation marks so that the expression is "> "++i" "? – ceno980 Sep 30 '17 at 12:54
  • Hi, no ++i is outside of two quoted strings, between ">" [++i HERE] " ", the last " " is just a space. – αғsнιη Sep 30 '17 at 13:52
0

As αғsнιη pointed out, you're inserting ++i as part of a literal string.

An alternative solution, which may look a bit prettier:

awk -F '>' '/^>/ { $1 = "> " ++i } { print }' file.fa

or, if you like the shorthand for { print },

awk -F '>' '/^>/ { $1 = "> " ++i } 1' file.fa

This uses > as the input field delimiter and replaces the first field (the bit before the >, which is empty in the input) on any header line with the required string.

| improve this answer | |
  • I know that $1 is the variable in which the first command line argument a user passes in is stored. In the context of awk, what does the $1 mean? – ceno980 Oct 1 '17 at 4:59
  • @ceno980 $1 in an awk program is the first field (column) of the current record (line). $2 will be the second, and so on. NF is the number of fields in the current record and $NF is thus the value of the last field. – Kusalananda Oct 1 '17 at 16:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.