2

I'm trying to find the first empty line after a match and replace it with my text. For example, if the pattern was Authors:

Authors
-----
author1
author2
author3
...
authorN

-----

I would want sed to append an additional author and a new line:

Authors
-----
author1
author2
author3
...
authorN
authorAdded

-----

These patterns are variable length and location across the file database.

Kusalananda
  • 14,885
  • 3
  • 41
  • 52
John
  • 29
  • 3
  • are there multiple such blocks? https://stackoverflow.com/questions/38972736/how-to-select-lines-between-two-patterns will get you started... you can use [{} grouping](https://www.gnu.org/software/sed/manual/sed.html#Common-Commands) to execute commands only on matching address – Sundeep Jul 14 '17 at 15:13

2 Answers2

5

This might work for you (GNU sed):

sed '/^Authors/!b;:a;n;/./ba;inew author' file

Print lines other those that begin with Authors as usual. Then print non-empty lines as usual and on the first empty line insert the required string. N.B. the empty line will also be printed

potong
  • 55,640
  • 6
  • 51
  • 83
  • Could you please explain a bit about `!b;:a;n;/./ba;`? Any pointer to the official docs would be okay too. Thank you! – Pothi Kalimuthu Apr 18 '18 at 03:00
  • 3
    @PothiKalimuthu the `!` after an address (in this case the address is one starting with `Authors`) is negated i.e. any address other than this one. The `:a` marks a place in the instructions (it could be named `:a_place_to_jump_to`). `n` prints the current line and refreshes it with the next. `/./` any line containing at least one character. `ba` means jump to the marker `a` (a loop is constructed which is only broken when an empty line is encounter or the end-of-file). `i` is insert into the output `new author` see [here](https://stackoverflow.com/tags/sed/info) – potong Apr 18 '18 at 06:30
  • Awesome. Thank you. – Pothi Kalimuthu Apr 18 '18 at 18:33
0

I think awk is your best bet here:

$ cat test.txt
Count
-----
1
2
3
4
5

-----

$ awk '{ if ($1=="") { print last+1; last=last+1; print ""; } else { print; last=$1 } }' test.txt 
Count
-----
1
2
3
4
5
6

-----
Jack
  • 5,801
  • 1
  • 15
  • 20
  • This is helpful but these files are rather large so I would prefer to stream in-place edit if I can. I edited the example to show more what I'm trying to do. – John Jul 14 '17 at 15:32
  • OK -- so if you have `Author5` then you want to add `Author6`? And if you have `Zimbabwe442` you want to add Zimbabwe443`? – Jack Jul 14 '17 at 15:41
  • No it's arbitrary, the list varies from file to file so it could be John, Shannon, Jack, but I want to add Jared everytime. So I want to append the same string every time its just that the number of authors vary. – John Jul 14 '17 at 15:46
  • Is there just ONE list per file, and you only want to add ONE line to each file, at the first blank line? – Jack Jul 14 '17 at 15:51
  • One list per file, one line per file. Not the first blank line but the first blank line after the pattern is found. – John Jul 14 '17 at 17:10