Grep only the matched values from the Input

Viewed 62

I have a tab limited file as like this

 chr20 102 K245 A T 56.0 AC.02 AC=0.1;DC=45;AC_old=452;DP=21;sample=kj;sample_name=DKl;New_sample=rdf
 chr10 8742 JH245 G T 86.0 AC.742 AC=2.1;DC=75;AC_old=42;DP=1;sample=KHS;sample_name=WEKl;New_sample=ASEf
 chrX 2302 XS245 G A 786.0 AC.452 AC=8;DC=5;AC_old=4A2;DP=5;sample=SED;sample_name=MHNSKl;New_sample=rdf

And Need to extract only AC,DC,sample as like this

 chr20 102 K245 A T 56.0 AC.02 AC=0.1 DC=45 sample=kj
 chr10 8742 JH245 G T 86.0 AC.742 AC=2.1 DC=75 sample=KHS
 chrX 2302 XS245 G A 786.0 AC.452 AC=8 DC=5 sample=SED

I have tried with grep as like this, but not served the purpose

 grep -wF "AC|DC|sample" < file.txt
3 Answers

You can use

awk -F\; '$1 ~ /AC|DC|sample/{print $1 OFS $2 OFS $5}' file

Here,

  • -F\; sets the field separator to ;
  • $1 ~ /AC|DC|sample/ only takes lines having AC, DC or sample in Field 1
  • {print $1 OFS $2 OFS $5} - prints Field 1, 2 and 5 with spaces as separators.

See the online demo:

s='chr20 102 K245 A T 56.0 AC.02 AC=0.1;DC=45;AC_old=452;DP=21;sample=kj;sample_name=DKl;New_sample=rdf
chr10 8742 JH245 G T 86.0 AC.742 AC=2.1;DC=75;AC_old=42;DP=1;sample=KHS;sample_name=WEKl;New_sample=ASEf
chrX 2302 XS245 G A 786.0 AC.452 AC=8;DC=5;AC_old=4A2;DP=5;sample=SED;sample_name=MHNSKl;New_sample=rdf'
awk -F\; '$1 ~ /AC|DC|sample/{print $1 OFS $2 OFS $5}' <<< "$s"

Output:

chr20 102 K245 A T 56.0 AC.02 AC=0.1 DC=45 sample=kj
chr10 8742 JH245 G T 86.0 AC.742 AC=2.1 DC=75 sample=KHS
chrX 2302 XS245 G A 786.0 AC.452 AC=8 DC=5 sample=SED

Could you please try following, written and tested with your shown samples only in GNU awk.

awk '
match($0,/AC\.[0-9]+/){
  val1=value=""
  val1=substr($0,1,RSTART+RLENGTH)
  num=split($NF,arr,";")
  for(i=1;i<=num;i++){
    if(arr[i]~/^(AC=|DC=|sample=)/){
      value=(value?value OFS:"")arr[i]
    }
  }
  print val1,value
}
'  Input_file

Explanation: Adding detailed explanation for above.

awk '                                    ##Starting awk program from here.
match($0,/AC\.[0-9]+/){                  ##using match function which matches regex AC\.[0-9]+ here.
  val1=value=""                          ##Nullifying val1 and value here.
  val1=substr($0,1,RSTART+RLENGTH)       ##val1 is having sub string of matched regex.
  num=split($NF,arr,";")                 ##Splitting last field into arr here.
  for(i=1;i<=num;i++){                   ##Going through all values of last field.
    if(arr[i]~/^(AC=|DC=|sample=)/){     ##Checking condition if last field is either AC= OR DC= OR sample= here.
      value=(value?value OFS:"")arr[i]   ##Create value which has array item value in it.
    }
  }
  print val1,value                       ##Printing val1 and value here.
}
'  Input_file                            ##mentioning Input_file name here.

You may use this awk:

awk -F '[\t;]+' -v OFS='\t' '{s=""; for (i=1; i<=6; ++i) s = (i == 1 ? "" : s OFS) $i; for (i=6; i<=NF; ++i) if ($i ~ /^([AD]C|sample)[=.]/) s = s OFS $i; print s}' file

chr20   102 K245    A   T   56.0    AC.02   AC=0.1  DC=45   sample=kj
chr10   8742    JH245   G   T   86.0    AC.742  AC=2.1  DC=75   sample=KHS
chrX    2302    XS245   G   A   786.0   AC.452  AC=8    DC=5    sample=SED

A more readable version:

awk -F '[\t;]+' -v OFS='\t' '
{
   s = ""
   for (i=1; i<=6; ++i)
      s = (i == 1 ? "" : s OFS) $i
   for (i=6; i<=NF; ++i)
      if ($i ~ /^([AD]C|sample)[=.]/)
         s = s OFS $i
   print s
}' file
Related