Sed: Complicated replace after pattern (on same line)

awk, sed

Solution

$ awk 'BEGIN{ FS=OFS="|" } $1~/ 00 /{gsub(/[^ ][^0 ]|[^0 ][^ ]/,"(&)",$2)} 1' file
  foobar 42                  | ff 00 00 00 00
  foobaz 00                  | (0a) 00 (0b) 00 00
  foobie 00                  | 00 00 00 00 00
  bar    00                  | (ab) (ba) 00 (cd) 00

In case the string you want to search for ever gets more complicated than 2 0s, here's a more generally extensible approach since it doesn't require you to write an RE that negates the string:

$ awk '
    BEGIN{ FS=OFS="|" }
    $1 ~ / 00 /{
        split($2,a,/ /)
        $2=""
        for (i=2;i in a;i++)
            $2 = $2 " " (a[i] == "00" ? a[i] : "(" a[i] ")")
    }
    1
' file
  foobar 42                  | ff 00 00 00 00
  foobaz 00                  | (0a) 00 (0b) 00 00
  foobie 00                  | 00 00 00 00 00
  bar    00                  | (ab) (ba) 00 (cd) 00

Problem

Suppose you have some text like this: ``` foobar 42 | ff 00 00 00 00 foobaz 00 | 0a 00 0b 00 00 foobie 00 | 00 00 00 00 00 bar 00 | ab ba 00 cd 00 ``` and you want to change all non-`00` on the right hand side of the `|` to be wrapped with `()`, but only if on the LHS of the `|` has `00`. The desired result: ``` foobar 42 | ff 00 00 00 00 foobaz 00 | (0a) 00 (0b) 00 00 foobie 00 | 00 00 00 00 00 bar 00 | (ab) (ba) 00 (cd) 00 ``` Is there a good way of going about this using sed, or am I trying to stretch beyond the capabilities of the language? Here's my work so far: `s/[^0]\{2\}/(&)/g` wraps your RHS values `/[^|]*00[^|]*|/` can be used as an address to a command to operate only on valid lines The trick now is to formulate a command that executes in a portion of the pattern space. This really isn't line oriented, which may explain why I'm having trouble getting an expression that works.

Original source