0

a file I need to extract info from looks like

2       41620   .       T       G       100     PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669

the output I need would be

2   41620   CSQ=G    missense_variant

the major fields are always divided by ||| but not that the 2 41620 is from the first field and the CSQ=G and missense variant is from the next. It does neither have to be missense_variant nor somethign along the lines but it is always the first and fourth field after the first |||.

How to achieve in perl , awk, sed or so?

4
  • 1
    Does whatever you seek to output always going to be in the same columns in the original ? If so, awk is the way to go here Feb 17, 2016 at 6:51
  • Writing answer, will post in a minute Feb 17, 2016 at 7:45
  • Answer posted. I'm off to sleep, as it's almost 1 am. Let me know if my answer helps and leave upvote if you like it. Feb 17, 2016 at 7:52
  • What's up ? I'm still here Feb 17, 2016 at 7:55

1 Answer 1

-1

Since you've mentioned that data is always in the same columns, AWK is appropriate for this task. However small thing is that You have data that is up to certain point has space as separator , but then switches to using vertical bar as separator. Thus we need a bit of more complex AWK hackery.

awk '{gsub(/[;]/," ");printf "%s %s ",$1,$2; for(i=1;i<=NF;i++){ if($i~/\|\|\|/) {gsub(/\|/," ");printf "%s %s",$(i+1),$(i+5);break} } printf "\n"; }' testData.txt

To put the above code into scripting form,

#!/usr/bin/awk -f 

{ 
  gsub(/[;]/," ");
  printf "%s %s ",$1,$2; 
  for(i=1;i<=NF;i++){ 
     if($i~/\|\|\|/) {
        gsub(/\|/," ");
        printf "%s %s",$(i+1),$(i+5);
        break
     } 
   } 
   printf "\n";
}

Put that into a file, call it myScript.awk or anything, add exec permissions withchmod +x myScript.awk and give it input file as argument

Sample run:

$ chmod +x dataExtract.awk
$ ./dataExtract.awk testData.txt                               
2 41620CSQ=G missense_variant

Side note: in the question you said missense_variant is 4th field, but actually that's 5th field in the example you've posted.I've adjusted accordingly

Edit as requested in comments:

#!/usr/bin/awk -f 

{ 
  gsub(/[;]/," ");
  printf "%s\t%s\t",$1,$2; 
  for(i=1;i<=NF;i++){ 
     if($i~/\|\|\|/) {
        gsub(/\|/," ");
        printf "%s\n" $(i+5);
        break
     } 
   } 
}
5
  • Ah . . . simple fix . . . Just add printf "\n" outside the for loop . . . I'll fix that up in a sec Feb 17, 2016 at 7:58
  • Well CSQ=A is the first field after the ||| part. Didn't you ask for first and fifth field after the ||| ? Feb 17, 2016 at 8:06
  • Also, 10642CSQ=A need to be spaced out to 10642 CSQ=A . I'll add a space to first printf statement Feb 17, 2016 at 8:07
  • Yes, possible missense_variant is the fifth field, so that's the $(i+5) part. If you want to get rid of CSQ=A remove the $(i+1) part , and change printf "%s %s" to printf "%s\t" . I'll make a small edit again in a sec Feb 17, 2016 at 8:11
  • OK . . . now i really gotta go. Good night ! Feb 17, 2016 at 8:15

You must log in to answer this question.

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