Det
Det

Reputation: 3710

regex - append after first match

Say I have the following kind of file:

a a c
b b c
c c c
d d c
e e c
a a c
b b c
c c c
d d c
e e c

How do I end up with:

a a c
b b c
c c c
—————
d d c
e e c
a a c
b b c
c c c
d d c
e e c

...without just adding the em dashes after the 3rd line (first line with c c c).

Upvotes: 0

Views: 117

Answers (2)

NeronLeVelu
NeronLeVelu

Reputation: 10039

sed '/c c c/!b
s/$/\
-----/
# Using buffer
:cycle
N
$!b cycle' YourFile
  • until first c c c, just print the line
  • add a line on line (so at 1st ccc)
  • load a line in buffer (and no print)
  • cycle the load until last line
  • last line print the whole (by exiting the loop, not the action like a new N cycle will do)

or alternative for huge file by using a small buffering

# without big buffer
:cycle
n
s/.*\n//
$!b cycle' YourFile
  • print 1st line and load a new one
  • remove first line
  • cycle if not the end

Upvotes: 1

Wintermute
Wintermute

Reputation: 44023

This awk will work:

awk '1; !flag && /c c c/ { flag = 1; print "—————" }' filename

That is:

1                   # first, print every line (1 meaning true here, so the
                    # default action -- printing -- is performed on all
                    # lines)
!flag && /c c c/ {  # if the flag is not yet set and the line we just printed
                    # matches the pattern:
  flag = 1          # set the flag
  print "—————"     # print the dashes.
}

Alternatively with sed (although I recommend using the awk solution):

sed -n 'p; /c c c/ { x; /^$/ { s//—————/; p }; x }' filename

This is a bit more complex. Knowing that the hold buffer is empty in the beginning:

p             # print the line
/c c c/ {     # if it matches the pattern:
  x           # exchange hold buffer and pattern space
  /^$/ {      # if the pattern space (that used to be the hold buffer) is
              # empty:
    s//—————/ # replace it with the dashes
    p         # print them
  }
  x           # and exchange again. The hold buffer is now no longer empty,
              # and the dash block will not be executed again.
}

Upvotes: 4

Related Questions