how to parse text into tab separated columns?

Viewed 82

I have a text file with lines that look like this

rnd-1_family-262#Unknown
rnd-1_family-263#LINE/I-Jockey
rnd-1_family-264#Unknown
rnd-1_family-265#DNA/TcMar-Mariner

and I want to get it into something like this, which is separate the text after the # and the / into tab-separated columns, with 2 'Unknowns' appearing when there is a single unknown ...

rnd-1_family-262 Unknown Unknown
rnd-1_family-263 LINE Jockey
rnd-1_family-264 Unknown Unknown
rnd-1_family-265 DNA TcMar-Mariner

I would appreciate any advice on how to do this in bash.

I attempted this in a round about way:

# gets the ID names
cat te-hierarchy.txt | awk -F '#' '{print $1}' > names.txt
# gets the stuff after the #
cat te-hierarchy.txt | awk -F '#' '{print $2}' > types.txt
# split that file to get 2 separate files 
cat types.txt | awk -F '/' '{print $1}' > order.txt
cat types.txt | awk -F '/' '{print $2}' > family.txt
# paste to create 3 cols
paste names.txt family.txt order.txt

However this means that there are blank spaces where there should be unknowns, how to insert this?

3 Answers

You may use this awk:

awk -F '[#/]' -v OFS='\t' 'NF == 2 {$3 = "Unknown"} {$1=$1} 1' file

rnd-1_family-262  Unknown  Unknown
rnd-1_family-263  LINE     I-Jockey
rnd-1_family-264  Unknown  Unknown
rnd-1_family-265  DNA      TcMar-Mariner

You can do something like this to separator the text using bash:

IN="rnd-1_family-262#Unknown"
arrIN=(${IN//#/ })
echo ${arrIN[1]}

I would use GNU AWK for this task following way, let file.txt content be

rnd-1_family-262#Unknown
rnd-1_family-263#LINE/I-Jockey
rnd-1_family-264#Unknown
rnd-1_family-265#DNA/TcMar-Mariner

then

awk 'BEGIN{FS="#|/";OFS="\t"}{$3=$3?$3:"Unknown";print}' file.txt

output

rnd-1_family-262    Unknown Unknown
rnd-1_family-263    LINE    I-Jockey
rnd-1_family-264    Unknown Unknown
rnd-1_family-265    DNA TcMar-Mariner

Explanation: I set field seperator to # or (|) / and output field seperator to tab. Then I set third column content ($3) to be either third column content or Unknown using ternary operator. Disclaimer: I assumed third column content is never 0.

(tested in gawk 4.2.1)

Related