Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a fasta file looking something like this:

>19 dna:chromosome chromosome:NCBIM37:19:1:61342430:1 37330562 ID13406 U -
>19 dna:chromosome chromosome:NCBIM37:19:1:61342430:1 37330584 ID57999 U -

The lines beginning with ">" are headers, the others data.

I want to remove all non-header lines that are shorter than 26 or longer than 31. I also want to remove the header belonging to those lines (i.e. the previous line.)

My code so far

awk '
{if (substr($0,1,1) == ">") 
    {if ((length($0) > 25) && (length($0) < 32)) {print $header "\n" $0}}}' *

but this gives me the error message

awk '{if (substr($0,1,1) == ">") {header=$0} else {if ((length($0) > 25) && (length($0) < 32)) {print $header $0}}}' *
), name "header"ld $(>19 dna:chromosome chromosome:NCBIM37:19:1:61342430:1 37330562 ID13406 U -
 input record number 2, file Cluster_1.fas
 source line number 1
share|improve this question
up vote 3 down vote accepted

Your problem is that you said:

print $header

..instead of:

print header

You want an un-interpolated variable content.

share|improve this answer

Looks like it's easier to solve it with sed:

sed '/^>/{N;/\n.\{26,31\}$/!d}'

small explanation:

/^>/ matches to a string with header
{} applies command group to a pattern
N appens next line to a pattern
/\n.\{26,31\}$/ checks if symbols count is between 26 .. 31
!d if matched just pass it, otherwise delete

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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