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?

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

2 Answers 2

0

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

awk '/^>/{sub(">", "> "++i " ")}1' infile
2
  • What is the reason for having to place ++i within its own set of quotation marks so that the expression is "> "++i" "?
    – ceno980
    Commented Sep 30, 2017 at 12:54
  • Hi, no ++i is outside of two quoted strings, between ">" [++i HERE] " ", the last " " is just a space. Commented Sep 30, 2017 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.

2
  • 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
    Commented Oct 1, 2017 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
    Commented Oct 1, 2017 at 16:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .