I tried writing an one liner in awk to convert a two column file into three column file.

i.e. chr name & start position --> chr name & if (Start>2000) then start -2000; else 0 & start position

So I wrote the below command.

for i in `ls *.startlist`; do 
name=`basename $i .startlist`; 
awk -vOFS="\t" '{for (i=1; i<= NF; i++) { if($2 < 2000) { print $1,0,$2} else {print $1,$2-2000,$2 } }}' $i >${name}_promoter.bed; 

but this prints every line twice. Can you suggest the error. and also do suggest if you have a better and faster way for the same.

  • 1
    Consider formatting your code with codeblocks so it's readable? – user13757 Mar 9 '17 at 10:37
  • I'd consider using a single ternary conditional instead e.g. awk '{print $1, $2 < 2000 ? 0 : $2 - 2000, $2}' – steeldriver Mar 9 '17 at 12:36

you are running your transformation NF times for every line. Your input has two fields, so it doubles every line of your output.

Try removing the for loop entirely and check if the result is as desired.


If the input file has two columns, there are two fields in each record (NF is 2) and the for loop is executed for i=1 and i=2 and each time a print is called.

'{for (i=1; i<= NF; i++) { if($2 < 2000) { print $1,0,$2} else {print $1,$2-2000,$2 } }}'

Just remove the loop.

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.