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.

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).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.