sed: renaming selective strings in a file

Viewed 38

I have a file called protein.faa, its content is:

>WP_004066472.1 MULTISPECIES: NADH-quinone oxidoreductase subunit K [Thermococcus]
MIPLQFVTAFLMIFMGIYAFLYKRNLIKLILALNLI
LVLTSIVIGVCVLSLAMALTINAYRHYGTLDVNKLRRLRG
>WP_004066568.1 MULTISPECIES: DNA-directed RNA polymerase subunit P [Thermococcus]
MVEALYKCAKCGKEF
>WP_004066764.1 MULTISPECIES: Lrp/AsnC ligand binding domain-containing protein [Thermococcus]
MVTAFILMVTAAGKEREVMEKLLTYPEVKEAYVVYG
>WP_004067064.1 MULTISPECIES: hypothetical protein [Thermococcus]
MEITIEKFKPKVTRPFKRKNEYWVKL
PSAKELVDEYFSE

I want to rename only names after each > to filename+its order number, i.e.:

>protein_1 MULTISPECIES: NADH-quinone oxidoreductase subunit K [Thermococcus]
MIPLQFVTAFLMIFMGIYAFLYKRNLIKLILALNLI
LVLTSIVIGVCVLSLAMALTINAYRHYGTLDVNKLRRLRG
>protein_2 MULTISPECIES: DNA-directed RNA polymerase subunit P [Thermococcus]
MVEALYKCAKCGKEF
>protein_3 MULTISPECIES: Lrp/AsnC ligand binding domain-containing protein [Thermococcus]
MVTAFILMVTAAGKEREVMEKLLTYPEVKEAYVVYG
>protein_4 MULTISPECIES: hypothetical protein [Thermococcus]
MEITIEKFKPKVTRPFKRKNEYWVKL
PSAKELVDEYFSE

My code is

name="$(echo protein.faa | sed 's/....$//')"
sed "s/>.*/>${name}/" protein.faa 

which allows me to get only

>protein
MIPLQFVTAFLMIFMGIYAFLYKRNLIKLILALNLI
LVLTSIVIGVCVLSLAMALTINAYRHYGTLDVNKLRRLRG
>protein
MVEALYKCAKCGKEF
>protein
MVTAFILMVTAAGKEREVMEKLLTYPEVKEAYVVYG
>protein
MEITIEKFKPKVTRPFKRKNEYWVKL
PSAKELVDEYFSE

How do I add order numbers and keep whatever goes after >protein_i?

2 Answers

This job suites gnu awk more:

awk -i inplace 'BEGINFILE {fn=FILENAME; sub(/\..*$/, "", fn); i=0} $1 ~ /^>/{$1 = ">" fn "_" ++i} 1' *.faa

>protein_1 MULTISPECIES: NADH-quinone oxidoreductase subunit K [Thermococcus]
MIPLQFVTAFLMIFMGIYAFLYKRNLIKLILALNLI
LVLTSIVIGVCVLSLAMALTINAYRHYGTLDVNKLRRLRG
>protein_2 MULTISPECIES: DNA-directed RNA polymerase subunit P [Thermococcus]
MVEALYKCAKCGKEF
>protein_3 MULTISPECIES: Lrp/AsnC ligand binding domain-containing protein [Thermococcus]
MVTAFILMVTAAGKEREVMEKLLTYPEVKEAYVVYG
>protein_4 MULTISPECIES: hypothetical protein [Thermococcus]
MEITIEKFKPKVTRPFKRKNEYWVKL
PSAKELVDEYFSE

To make it more readable for gnu awk:

awk -i inplace 'BEGINFILE {
   fn = FILENAME
   sub(/\..*$/, "", fn)
   i = 0
}
$1 ~ /^>/{
   $1 = ">" fn "_" ++i
} 1' *.faa

For non-gnu awk:

for f in *.faa; do
   awk 'BEGINFILE {fn=FILENAME; sub(/\..*$/, "", fn)} $1 ~ /^>/{$1 = ">" fn "_" ++i} 1' "$f" > _tmp && mv _tmp "$f"
done

Use this Perl one-liner:

perl -pe 'BEGIN { $i = 1; chomp( $basename = `basename $ARGV[0] .faa` ); } s{^>\S+}{>${basename}_${i}} and $i++; ' in.faa > out.faa

To change file in-place:

perl -i.bak -pe 'BEGIN { $i = 1; chomp( $basename = `basename $ARGV[0] .faa` ); } s{^>\S+}{>${basename}_${i}} and $i++; ' in.faa

The Perl one-liner uses these command line flags:
-e : Tells Perl to look for code in-line, instead of in a file.
-p : Loop over the input one line at a time, assigning it to $_ by default. Add print $_ after each loop iteration.
-i.bak : Edit input files in-place (overwrite the input file). Before overwriting, save a backup copy of the original file by appending to its name the extension .bak.

SEE ALSO:
perldoc perlrun: how to execute the Perl interpreter: command line switches
perldoc perlre: Perl regular expressions (regexes)
perldoc perlrequick: Perl regular expressions quick start

Related