I prefer to use awk for this, since then I don't need to worry about escaping:
Code:
awk -v "n=line-number" -v "s=line to insert" '(NR==n) { print s } 1' input-file
First line is line number 1. If the file is too short, it will not insert anything.
This second variant will append the line, if the line number is larger than the number of lines in the file. It will not add empty lines, though; just the line to be inserted:
Code:
awk -v "n=line-number" -v "s=line to insert" '
(NR==n) { n=-1 ; print s }
{ print $0 }
END { if (n>0) print s }' input-file
To do the above safely to any file, I'd write a small shell script. I prefer Bash, but since I don't know which shell you prefer, here's something that should work with any /bin/sh. Note, this is untested code:
Code:
#!/bin/sh
LINENUM=55
LINESTR="inserted line"
if [ ":$*" = ":" ] || [*":$*" = ":-h" ] || [ ":$*" = ":--help" ]; then
exec >&2
echo ""
echo "Usage: $0 [ -h | --help ]"
echo " $0 filename(s)"
echo ""
exit 0
fi
WORK=`mktemp -d` || exit $?
trap "rm -rf '$WORK'" EXIT
while [ $# -gt 0 ]; do
if [ ! -f "$1" ]; then
echo "$1: File not found." >&2
exit 1
fi
awk -v "n=$LINENUM" -v "s=$LINESTR" '
(NR==n) { n=-1; print s }
{ print $0 }
END { if (n>0) print s }'
' "$1" > "$WORK/temp" || exit $?
chown --reference="$1" "$WORK/temp" 2>/dev/null
chmod --reference="$1" "$WORK/temp" 2>/dev/null
mv -f "$WORK/temp" "$1" || exit $?
echo "$1: Modified." >&2
shift 1
done