Print column next to the column matching a pattern

Viewed 359

I have this tab separated file:

gene        1  A  6  gene_name  TP53       B
exon        6  B  2  2          A          gene_name  MYC2  10.0  B
transcript  3  B  B  4          gene_name  ORF1

How can I print the first column plus the next column after gene_name column? As you can see, gene_name do not exist always in the same column.

I am not sure about how to get the last part of this:

awk 'BEGIN{OFS="\t"} {print $1, ??}' myFile.tsv

So, my expected output is:

gene TP53
exon MYC2
transcript ORF1

Thanks!

5 Answers

With your shown samples, please try following.

1st solution: In case you have multiple gene_name values in single line then following may help.

awk 'BEGIN{FS=OFS="\t"} {for(i=1;i<=NF;i++){if($i=="gene_name"){print $1,$(i+1);i++}}}' Input_file

2nd solution: In case you have only 1 gene_name then use following.

awk 'BEGIN{FS=OFS="\t"} {for(i=1;i<=NF;i++){if($i=="gene_name"){print $1,$(i+1);next}}}' Input_file

3rd solution: With your very specific case where gene_name always coming on 3rd field we could try this one, for Generic ones try 1st or 2nd solutions.

awk 'BEGIN{FS=OFS="\t"} $3=="gene_name"{print $1,$4}' Input_file

OR if you want to check 2nd last field and print last field value then use:

awk 'BEGIN{FS=OFS="\t"} $(NF-1)=="gene_name"{print $(NF-1),$NF}' Input_file

4th solution: With sed please try following.

sed -E 's/(\S+).*gene_name\s+(\S+).*/\1\t\2/' Input_file

You may use this gnu awk solution:

awk '{print gensub(/^(\S+).*\tgene_name\t(\S+).*/, "\\1\t\\2", "1")}' file
gene    TP53
exon    MYC2
transcript  ORF1

Using GNU grep:

grep -oP '(^\S+)|(\bgene_name\s+\K\S+)' myFile.tsv | paste - -
$ awk -v OFS='\t' '{v=$1; sub(/.* gene_name /,""); print v, $1}' file
gene    TP53
exon    MYC2
transcript      ORF1

And also with awk:

awk -v FS=' .*gene_name | ' '{print $1,$2}' file
gene TP53
exon MYC2
transcript ORF1
Related