The sed
expression $s/$/'/
adds a single quote to the end of the last line of input. The first $
is the "address" of the last line. When the last line is found, this triggers the given substitution, s
, command. That command replaces the end of the line, matched by $
in the regular expression, with a single quote.
Would you want to perform the substitution only if the line does not already have a single quote at the end of it, then use $s/[^']$/&'/
. This replaces the last character on the last line with itself, followed by a single quote, but only if that last character is not a single quote. Of course, this does require that there is at least one character on the line already.
In the shell, you can use these sed
expressions in double-quotes, but you need to escape the two dollar signs from the shell:
sed "\$s/\$/'/" file
sed "\$s/[^']\$/&'/" file
If your sed
supports it, you may use it with -i
to perform an in-place edit on the file.
To apply this on only the last non-blank line in the file (and also delete the trailing blank-only lines), first, delete the blank lines at the end of the file. One way to do this is with the following pipeline:
tac file | sed '1,/[[:graph:]]/ { /[[:graph:]]/!d; }' | tac
This reverses the lines of the file with GNU tac
, removes all lines up to the first non-blank line ("non-blank" meaning it has some graph character on it; you could use [^[:space:]]
in place of [[:graph:]]
), and then reverses the lines again.
Modifying the last line of this pipeline's output:
tac file | sed '1,/[[:graph:]]/ { /[[:graph:]]/!d; }' | tac |
sed "\$s/\$/'/" >file.new
Or, combining the two sed
invocations:
tac file | sed "1,/[[:graph:]]/ { /[[:graph:]]/\!d; s/\$/'/; }" | tac >file.new
(Note the escaping of !
without which some shell may try to do a history expansion.)
... then just replace file
with file.new
using mv
.