How to remove the last line of all files from a directory?
You can use this nice oneliner if you have GNU sed
.
sed -i '$ d' ./*
It will remove the last line of each non-hidden file in the current directory. Switch -i
for GNU sed
means to operate in place and '$ d'
commands the sed
to delete the last line ($
meaning last and d
meaning delete).
The other answers all have problems if the directory contains something other than a regular file, or a file with spaces/newlines in the file name. Here's something that works regardless:
find "$dir" -type f -exec sed -i '$d' '{}' '+'
find "$dir" -type f
: find the files in the directory$dir
-type f
which are regular files;-exec
execute the command on each file foundsed -i
: edit the files in place;'$d'
: delete (d
) the last ($
) line.'+'
: tells find to keep adding arguments tosed
(a bit more efficient than running the command for each file separately, thanks to @zwol).
If you don't want to descend into subdirectories, then you can add the argument -maxdepth 1
to find
.
Using GNU sed -i '$d'
means reading the full file and making a copy of it without the last line, while it would be a lot more efficient to just truncate the file in place (at least for big files).
With GNU truncate
, you can do:
for file in ./*; do
[ -f "$file" ] &&
length=$(tail -n 1 "$file" | wc -c) &&
[ "$length" -gt 0 ] &&
truncate -s "-$length" "$file"
done
If the files are relatively small, that would probably be less efficient though as it runs several commands per file.
Note that for files that contain extra bytes after the last newline character (after the last line) or in other words if they have a non-delimited last line, then depending on the tail
implementation, tail -n 1
will return only those extra bytes (like GNU tail
), or the last (properly delimited) line and those extra bytes.