9

I have a file like shown below. The 9th column has values joined by **.

chrXV   234346  234546  snR81   +       SNR81   chrXV   234357  0.0003015891774815342**0.131826816475   +
chrXV   234346  234546  snR81   +       SNR81   chrXV   234385  0.0002208827994288481**0.0118547789578  +
chrXV   234346  234546  snR81   +       SNR81   chrXV   234396  0.0001799579220002955**0.00583993781634 +
chrXV   234346  234546  snR81   +       SNR81   chrXV   234410  0.003451057940295026**0.00352844797952  +

I want to have an output where I can have the 2 values as sep columns. How can I do this in awk.

This is the output I want. Showing the first line of the output:

chrXV   234346  234546  snR81   +   SNR81   chrXV   234357  0.0003015891774815342   0.131826816475  +
1
  • 2
    Please always specify your column separator. Since this is a gff file, I assume it's tab separated but people won't know this unless you state it.
    – terdon
    Sep 23, 2014 at 9:08

5 Answers 5

8

No idea why people are using cat to pipe the file into awk, and the tr answer only translates one character into another, so any * is converted to a space.

Simple awk solution

awk -F"**" '$1=$1' OFS="\t" file 

For tab between all fields

awk 'sub(/\*\*/," "){$1=$1}1' OFS="\t" file

And one more

awk 'gsub(/(*| )+/,"\t")' file

Sed command

sed 's/[* ]\+/\t/g' file

tr command

tr -s '* ' '\t'  < file
1

Does it have to be awk? Why not cat file | tr '**' ' ' Just replacing the **'s with three spaces

9
  • tr '**' '\t' works too. Wanted it as tab separated. Does 3 spaces equivalent to a tab?. I want to see how awk would do this? Sep 22, 2014 at 19:23
  • How about cat file | awk -F "**" '{print $1 "\t" $2}'
    – kevino_17
    Sep 22, 2014 at 19:28
  • 1
    With a single space I'd use a gsub as follows cat file| awk '{gsub("[**| ]","\t"); print $0 }'
    – kevino_17
    Sep 22, 2014 at 19:45
  • 4
    I don't think tr does what you think it does. It transliterates one character at a time so I am not sure how you could get it to replace two *s with three spaces
    – iruvar
    Sep 22, 2014 at 20:00
  • 1
    @kevino_17 why are you using cat when awk takes files as arguments ?
    – user78605
    Sep 23, 2014 at 8:54
1
cat text.txt  |awk '{ split($9,a , "**"); printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",$1,$2,$3,$4,$5,$6,$7,$8, a[1], a[2],$10); }'

Output is:

chrXV   234346  234546  snR81   +   SNR81   chrXV   234357  0.0003015891774815342   0.131826816475  +
chrXV   234346  234546  snR81   +   SNR81   chrXV   234385  0.0002208827994288481   0.0118547789578 +
chrXV   234346  234546  snR81   +   SNR81   chrXV   234396  0.0001799579220002955   0.00583993781634    +
chrXV   234346  234546  snR81   +   SNR81   chrXV   234410  0.003451057940295026    0.00352844797952    +
0

Replacement of one substring by another is clearly work for sed. If you want it in awk, I assume you wish to do some additional processing by awk. To do so, you should just use the regex field separator:

awk -F'(**| )' '{.you code here.; print $10}'
6
  • That regex is awful and wont work. -1 for the fact that you also have answered as though you understand what you are doing.
    – user78605
    Sep 23, 2014 at 10:27
  • Could you please explain why regex is "awful" and also what is the reason it "wont work". I have no idea. I tested it before posting and it does work perfectly.
    – gena2x
    Sep 24, 2014 at 18:25
  • What do you think it does ?
    – user78605
    Sep 25, 2014 at 7:23
  • It uses either ' **' or ' ' as column separator - something that nobody else suggested in other answers. And leaves the exact way of output for author.
    – gena2x
    Sep 25, 2014 at 10:27
  • I know what you were trying to do, how does using '' as column separator do what OP wants in any way, also it won't separate based on two * as the there is a space before and after it in the regex. Honestly i don't even know why i am explaining this to you as i don't understand how after looking at your code you still don't see how it is completely wrong in every way. Try -F'(*| )+' as this would do what you think your current code does.
    – user78605
    Sep 25, 2014 at 10:56
0
awk -F'**' 'BEGIN{OFS="   ";} {print $1,$2}' file

use '**' as separator and set three whitespaces as output separator

You must log in to answer this question.

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