Travis Griggs
Travis Griggs

Reputation: 22252

Replace all but first space with tabs

I have a chain of piped bash commands

grep A01929 test_FTF89MNR.txt |
    grep status |
    tr "=" " " |
    tr "," " " |
    cut -d" " -f 1 -f 2 -f 11 -f 14 -f 17

which produces a whole bunch of output that looks like this

...    
2016-02-25 09:15:01.41 2742 1535 1796
...

To make import into Excel easy, I want to replace all of the white space between columns with TABS except the first one which separates the data and time. So the target output would be

...    
2016-02-25 09:15:01.41\t2742\t1535\t1796
...

Is there an easy command line fu that I can tack on to my chain of pipes to accomplish that? tr didn't seem to have something that allowed it to do ranges. I'm on OS X.

Upvotes: 0

Views: 367

Answers (5)

zzevannn
zzevannn

Reputation: 3714

Getting cute with sed could help you - replace them all then replace the first back, e.g.

sed 's/ /\t/g; s/\t/ /1'

e.g.

$ echo "2016-02-25 09:15:01.41 2742 1535 1796" | sed 's/ /\t/g; s/\t/ /1' 2016-02-25 09:15:01.41 2742 1535 1796

As pointed out in the comments, this is mac so that won't work. Here's a link to how to handle tabs on mac though.

Or, here's an all AWK version replacing all the pipes. awk '$0 ~ /A01929/ && $0~/status/ {gsub("=",""); gsub(",",""); print $1 " " $2 "\t" $11 "\t" $14 "\t" $17}' test_FTF89MNR.txt

Matches both the grepped values on a line, then substitues , and = for nothing, and then prints the desired delimiters.

Upvotes: 3

miken32
miken32

Reputation: 42714

To expand on the answer Merlin gave suggesting awk, you could replace your use of cut with awk, instead of doing additional post-processing. And you can replace your two calls to tr with one:

grep A01929 test_FTF89MNR.txt |
    grep status |
    tr "=," " " |
    awk '{print $1 " " $2 "\t" $11 "\t" $14 "\t" $17}'

With an excerpt from the original file, I'm sure someone could come up with an all-awk version.

Upvotes: 1

dawg
dawg

Reputation: 103834

If you have fixed field data, you can use a read loop in Bash:

txt="2016-02-25 09:15:01.41 2742 1535 1796" 

while read -r da ti f1 f2 f3
do 
    printf "%s %s\t%s\t%s\t%s" $da $ti $f1 $f2 $f3
done <<< $txt

Upvotes: 0

merlin2011
merlin2011

Reputation: 75555

You could use awk to specify the delimiters exactly.

awk '{print $1 " " $2 "\t" $3 "\t" $4 "\t" $5}' Input.txt

Upvotes: 4

Dirk Herrmann
Dirk Herrmann

Reputation: 5939

You could use the following trick with sed: First replace all blanks with tabs, then replace exactly one. Here's an example for illustration:

echo "a b c d" | sed 's/ /:/g;s/:/ /'

The first sed command s/ /:/g replaces globally (hence the g) all blanks with colons, and the second replaces the first colon with a blank. This turns the string a b c d into a b:c:d.

Upvotes: 1

Related Questions