Ohssie Ohssie - 3 months ago 11
Linux Question

Adding a new line to a growing paragraph using bash

I'm trying to write a bash script that adds a new line to a continually growing paragraph of a file. For every time I run the script it should add a new line to that paragraph but instead it returns the entire content of the file.

Here's my code...

function registerServiceProvider {
# register service provider inside config/app.php
sed '/App\Providers\*::class,/a \ App\Providers\${repoName}${provider}::class,' ./config/app.php


By default sed prints the resulting stream to stdout. If you have GNU sed you can use -i to modify the file in-place. With many BSD sed you can use -i but it requires an argument which will be the extension added to the backup file created.

If you want to stay more POSIXy you can redirect the output to a new file, then move that temp file over the old name (or redirect the output to make sure you don't change the permissions). Don't try to do it with redirection in one step though, because the first thing the shell will do is truncate the file, then you'll try to read it and it will be empty.

So, with GNU sed you can do:

sed -i -e '/App\Providers\*::class,/a \ App\Providers\${repoName}${provider}::class,' ./config/app.php

or with BSD (or GNU, the argument works but is optional with GNU)

sed -i .bak -e '/App\Providers\*::class,/a \ App\Providers\${repoName}${provider}::class,' ./config/app.php

or portably

sed '/App\Providers\*::class,/a \ App\Providers\${repoName}${provider}::class,' ./config/app.php > tmp_paragraph
cat tmp_paragraph > ./config/app.php
rm tmp_paragraph

If you want the repoName and provider variables to be shell variables that get expanded you need to put the sed script in double quotes. bash doesn't expand variables inside single quoted strings. So to take the GNU sed example you would change it to use double quotes like so:

sed -i -e "/App\\\\Providers\\\\*::class,/a \\ App\\\\Providers\\\\${repoName}${provider}::class," ./config/app.php

and note that we had to do plenty of extra escaping of the slashes, since bash will treat them as escape characters inside double quotes. We can use the single quotes to help with that as long as we put the variables outside it though (and note that I'm still going to double the quotes because I think you meant to do that to get actual back slashes in those spots)

sed -i -e '/App\\Providers\\*::class,/a \ App\\Providers\\'${repoName}${provider}'::class,' ./config/app.php