Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'd like to write a script in sed to insert line to a file after all similar lines in the file. So I need to locate the last match for a pattern and insert immediately after it. It's very unlikely that this would be the last line in the file.

I've seen a number of solutions that employ multiple piped calls to sed or use other tools such as tac. These are not appropriate - I need a pure sed solution that can be embedded inside a larger script that makes other changes to the same file.

I've been searching for a while but suspect it isn't possible. I thought I'd ask on here before giving up!

In case specifics help explain, I want to locate the last "Include" directive in an Apache http.conf file and insert another one beneath the last one.

share|improve this question
    
can you explain what's bad with using tac (or just awk, for that matter)? why do you need pure sed only? –  Philomath Jul 22 '11 at 12:09
    
I was trying to achieve one script that I can apply all changes to the file in one go. Yes I could do different changes in different ways but I hoped to self-contain all alterations to one file in one script. There's nothing wrong with tac/awk/grep/sed combinations - I've used them many times. For this particular problem I wanted to get a single sed solution. –  starfry Jul 22 '11 at 12:22
    
When researching I found this but could never get it to work: info.birnamdesigns.com/wiki/Sed_insert_after_last_match –  starfry Jul 24 '11 at 14:22

2 Answers 2

up vote 3 down vote accepted

Technically, the script below (minimally tested) seems to do what you require. The principle is to store lines in the hold space; when an include line is encountered, print all accumulated lines and clear the hold space; at the end of the input, prepend new to the accumulated lines and print.

#n
H
$ {
  g
  s/^/new/
  p
  b
}
/include/ {
  g
  s/^\n//
  p
  s/.*//
  h
  b
}

This is unlikely to integrate well into an existing sed script. You're really stretching sed's abilities there.

An Apache configuration file fits easily into memory. Don't use a streaming editor for it, load it up in a decent tool like Perl or Python, or at least awk.

share|improve this answer
    
I think you're right, this is pushing sed to its limits. I think it's a wonderful tool and like to see what it can do. Perhaps, for once, it isn't the right tool for the job. –  starfry Jul 22 '11 at 20:03

There is probably a real solution in sed that somebody else will pitch in, but a long time ago I solved the same scenario with this hack.

I placed a small comment "marker" at the point in the config file that I wanted new insert something with a script. Say:

#(Insert includes here)

Then you can use simple search and replace with that string as the search parameter and replace it with your new include PLUS the original comment line.

share|improve this answer
    
yes I will probably do something like that if I can't get a full solution based on Sed. Hopefully someone will come up with that real solution... –  starfry Jul 22 '11 at 12:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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