If all you want to do is add text to the last line, it's very easy with sed. Replace $
(pattern matching at the end of the line) by the text you want to add, only on lines in the range $
(which means the last line).
sed '$ s/$/ and Linux/' <file >file.new &&
mv file.new file
which on Linux can be shortened to
sed -i '$ s/$/ and Linux/' file
If you want to remove the last byte in a file, Linux (more precisely GNU coreutils) offers the truncate
command, which makes this very easy.
truncate -s -1 file
A POSIX way to do it is with dd
. First determine the file length, then truncate it to one byte less.
length=$(wc -c <file)
dd if=/dev/null of=file obs="$((length-1))" seek=1
Note that both of these unconditionally truncate the last byte of the file. You may want to check that it's a newline first:
length=$(wc -c <file)
if [ "$length" -ne 0 ] && [ -z "$(tail -c -1 <file)" ]; then
# The file ends with a newline or null
dd if=/dev/null of=file obs="$((length-1))" seek=1
fi
Another command that can add newlines if needed is awk
, so:
awk 1 ./*.txt
The 1 here is the simplest way to get a true condition in awk, which works for this purpose since awk default action on true conditions is to print the input lines.
Best Answer
To recursively sanitize a project I use this oneliner:
Explanation:
git ls-files -z
lists files in the repository. It takes an optional pattern as additional parameter which might be useful in some cases if you want to restrict the operation to certain files/directories. As an alternative, you could usefind -print0 ...
or similar programs to list affected files - just make sure it emitsNUL
-delimited entries.while IFS= read -rd '' f; do ... done
iterates through the entries, safely handling filenames that include whitespace and/or newlines.tail -c1 < "$f"
reads the last char from a file.read -r _
exits with a nonzero exit status if a trailing newline is missing.|| echo >> "$f"
appends a newline to the file if the exit status of the previous command was nonzero.