I would like to insert new string at last line staring with some text using sed, [closed]

Search the file for the last line with a given String to add a line after that match. Example:

Input:

Apple
Banana
Apple
Orange
Apple
Grapefruit

Output:

Apple
Banana
Apple
Orange
Apple
I am new string replaced at last apple
Grapefruit

Solution 1:

With GNU sed you can do this:

sed ':a;N;$! ba;s/.*\nApple/&\nYour appended line/'

The pattern :a;N;$! ba appends lines from the file to the buffer with N while the end of the file ($ address) is not (!) reached (jump to :a with ba). So if you exit the loop, all lines are in the buffer and search pattern .*\nApple matches the whole file up to the last line starting with Apple. The & in the replacement string insert the whole match and appends your text.

A portable solution working on other sed versions as well would be

sed -e ':a' -e 'N;$! ba' -e 's/.*\(\n\)Apple/&\1Your appended line/'

Here the script is split at the labels and instead of using \n in the replacement string (which is not guaranteed to work with non-GNU seds) we refer to the one from the pattern surrounded with \(\) with the \1 reference.

Solution 2:

I saw this example here

sed -i -e "\$aTEXTTOEND" <filename>

Information:

i: edit files in place    
e: add the script to the commands to be executed    
$: sed address location
a: append command
TEXTTOEND: text to append to end of file

Solution 3:

I assume that your example input is a file named fruits.txt.


If you want to insert a line after the last occurrence of "Apple", this can be done with sed like this:

sed -rz 's/(^(.*\n)?Apple)(\n|$)/\1\ninserted line\n/'

The -r option enables extended regular expressions.
The -z option tells sed to take NUL characters (ASCII code 0) as line separators instead of the normal newline characters. This way, the whole text file will be processed at once instead of line by line.

The sed command s/PATTERN/REPLACEMENT/ searches for the (extended, because of -r) regular expression in PATTERN and replaces it with the evaluated REPLACEMENT string.

The regular expression (^(.*\n)?Apple)(\n|$) matches any number of lines from the beginning (^) to the last occurrence of Apple followed by a line break (\n) or the end of the file ($).

Now this whole match gets replaced with \1\ninserted line\n, where \1 stands for the original content of the first match group, i.e. everything up to Apple. So actually it inserts inserted line preceded and followed by a line break (\n) right after the last occurrence of "Apple".

This also works if the "Apple" line is the first, last or only line in the file.

Example input file (added one line to your example, to make the behaviour clear):

Apple
Banana
Apple
Orange
Apple
Cherry

Example output:

Apple
Banana
Apple
Orange
Apple
inserted line
Cherry

If you are happy with the result and want to edit fruits.txt in place, instead of just outputting the modification, you can add the -i option:

sed -irz 's/(^(.*\n)?Apple)(\n|$)/\1\ninserted line\n/'

If you just want to append a line of text to the end of that file though, sed is not the optimal tool.

You can simply use Bash's >> appending output redirection then:

echo "I am new string replaced at last apple" >> fruits.txt

The >> will take the standard output of the command on its left (the echo command here simply prints its arguments to standard output) and appends it to the file specified on is right. If the file does not exist yet, it will be created.