insert EOF statement before the last line of file
To keep the same sort of here-document format and to insert the given text immediately before the last line of the file, try ed!
ed -s /etc/security/limits.conf << EOF
$ i
* soft nproc 65535
* hard nproc 65535
* soft nofile 65535
* hard nofile 65535
root soft nproc 65535
root hard nproc 65535
root soft nofile 65535
root hard nofile 65535
.
wq
EOF
This sends a sequence of commands to ed, all in a here-document. We address the last line in the file with $
and say that we would like to i
nsert some text. The text follows, just as in your example; once we're done with the inserted text, we tell ed we're done with a single period (.
). W
rite the file back to disk and then q
uit.
If you wanted to collapse the $ i
to $i
you'd want to escape the dollar sign or use a quoted here-document (ed -s input << 'EOF' ...
) to prevent $i
from expanding to the current vale of the i
variable or empty if there's no such variable set.
You can use ex
(which is a mode of the vi
editor) to accomplish this.
You can use the :read
command to insert the contents into the file. That command takes a filename, but you can use the /dev/stdin
pseudo-device to read from standard input, which allows you to use a <<EOF
marker.
The :read
command also takes a range, and you can use the $-
symbol, which breaks down into $
, which indicates the last line of the file, and -
to subtract one from it, getting to the second to last line of the file. (You could use $-1
as well.)
Putting it all together:
$ ex -s /etc/security/limits.conf -c '$-r /dev/stdin' -c 'wq' <<EOF
* soft nproc 65535
* hard nproc 65535
* soft nofile 65535
* hard nofile 65535
root soft nproc 65535
root hard nproc 65535
root soft nofile 65535
root hard nofile 65535
EOF
The -s
is to make it silent (not switch into visual mode, which would make the screen blink.) The $-r
is abbreviated (a full $-1read
would have worked as well) and finally the wq
is how you write and quit in vi
. :-)
UPDATE: If instead of inserting before the last line, you want to insert before a line with specific contents (such as "# End of file"), then just use a /search/
pattern to do so.
For example:
$ ex -s /etc/security/limits.conf -c '/^# End of file/-1r /dev/stdin' -c 'wq' <<EOF
...
EOF