0

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.

miken32
  • 42,008
  • 16
  • 111
  • 154
Travis Griggs
  • 21,522
  • 19
  • 91
  • 167
  • Showing input is always fine. Are we fine when tr replaces everything into tabs? And is A01929 always coming in ftont of status? Perhaps you can use something like `grep "A01929.*status" test_FTF89MNR.txt | tr "=," "\t" | cut -f1 -f2 -f11 -f14 -f17` (assuming only the date/time in the original file has a space). – Walter A Feb 26 '16 at 22:44

5 Answers5

4

You could use awk to specify the delimiters exactly.

awk '{print $1 " " $2 "\t" $3 "\t" $4 "\t" $5}' Input.txt
merlin2011
  • 71,677
  • 44
  • 195
  • 329
3

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.

Community
  • 1
  • 1
zzevannn
  • 3,414
  • 2
  • 12
  • 20
  • 1
    In another comment trouble inputting literal tabs was reported since this is Mac - this would help here http://stackoverflow.com/questions/5398395/how-can-i-insert-a-tab-character-with-sed-on-os-x – zzevannn Feb 26 '16 at 20:37
  • 1
    You should edit your answer to include this information, if you know that your current answer will not work. – miken32 Feb 26 '16 at 20:52
  • `/A01929/ && /status/` is enough. Setting `-F'[=, ]` will eliminate gsubs, also if you set `OFS='\t'` will be cleaner for `print $1 " " $2, $11, $14, $17` – karakfa Feb 26 '16 at 22:35
1

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.

Dirk Herrmann
  • 5,550
  • 1
  • 21
  • 47
1

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.

miken32
  • 42,008
  • 16
  • 111
  • 154
  • Here's all awk: `awk '$0 ~ /A01929/ && $0 ~ /status/ {gsub("=",""); gsub(",",""); print $1 " " $2 "\t" $11 "\t" $14 "\t" $17}' test_FTF89MNR.txt` – zzevannn Feb 26 '16 at 21:21
0

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
dawg
  • 98,345
  • 23
  • 131
  • 206