2

.

I have a text file similar to this:

A
B
C
D
E
F
G

and I need to:

  1. move line E before line C;
  2. replace line C with X (X could be multiline);
  3. replace line G with Y (Y could be multiline);
  4. remove lines D and F.

This is the sed file I have now:

/C/ c\
X
/G/ c\
Y
/D/ d
/F/ d

which does 2, 3, 4 but not 1. How can I fix the script to move E before C?

Note: I cannot rely on line numbers or contiguity of lines, which may vary; I can only rely on pattern matching.

1 Answer 1

5

For your particular case, this will do:

sed '
/C/,/E/ {
        s/[CD]/&/
        t s
        s/E.*/&\
X1\
X2/
        t e
        H
        :s
        d
        :e
        p
        x
        D
}
/F/d
/G/c\
Y1\
Y2
' file

Someone smarter than me may be able to do it in a simpler way -- notice that this should handle the case where there are other lines than D between C and E. This assumes however that the A, B, ... lines are sorted, ie no G between C and D.

Generally, cases like this are done much more obviously with ed or ex:

$ ed <<'EOT' -s file
/E/m/C/-1
g/D/d
g/F/d
/C/c
X1
X2
.
/G/c
Y1
Y2
.
w
EOT

$ cat file
A
B
E
X1
X2
Y1
Y2

The /PAT1/m/PAT2/-1 command will move the line matching PAT1 before the line matching PAT2.

The /PAT/c command will change the line matching PAT to the following lines terminated by ..

The g/PAT/d command will go to all lines matching PAT and delete them.

I've changed the order of the operations based on @don_crissti's suggestions, in order to make the example a bit more general (handle the case where the X1, Y1 inserted lines may match the /D/ or /F/ patterns).

0

You must log in to answer this question.

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