3

I'm using sed on Linux, trying to match data lines having three fields, tab separated (but the separation could be any whitespace), as in:

 12.3 0a 1b
 15.5 0v 1h
 17.7 5k 3c

; right now I'm using this:

sed -n 's/^\([^[:blank:]]*\)[[:blank:]]*\([^[:blank:]]*\)[[:blank:]]*\([^[:blank:]]*\)/\1\t\3\t\2/p' mydata.txt

... so I'm able to extract and manipulate (in the example, just position inversion) individual fields via \1, \2, \3.

Is there a better way to specify this?

Cheers!

2
  • 2
    sed may not be the best tool for this. Is ther a particular reason you don't want to use awk, or perl or something better suited? Nov 28, 2011 at 18:39
  • Hi @dmckee - usually, I'm not that well acquainted with awk or perl, so whenever I have a "field inversion in text data" problem like this, the first thing I think of is what I know: "\2 \1" which is something I get from sed. However, sed not being suited for the task is also an answer I appreciate (since as I said, that's not the first thing that pops to my mind when I have this problem)... Cheers!
    – sdaau
    Nov 28, 2011 at 19:20

1 Answer 1

5

A trivial example in awk to suggest what can be done

awk '{print $2 $1 $3}` < input_file.txt

simply rearranges the first two fields while printing all three on all lines.

To rearrange those lines have exactly three fields, preserve any that start with # (i.e. comment in sh-like languages) and delete all others

awk `/^#/{print $0;next} NF==3{print $2 $1 $3;next} {}' < input_file.txt

Most unix systems have a fairly complete awk man-page.

The important this for your purposes here is that the fields are accessibly with $1, $2, ..., where "field" is defined as strings of stuff separated by FS (i.e. the field separator) which defaults to (a space).

1
  • Many thanks for that, @dmckee - awk indeed seems better for the job; cheers!
    – sdaau
    Nov 28, 2011 at 23:51

You must log in to answer this question.

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