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 sed
s) 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.