I have a document with a lot of empty lines.
How can I remove them when there are 2 or more together.
I tried sed "s/\n\n//"
file but it didn't work. No error.
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communitysed '/^$/d'
sed
is line-oriented, so thinking in terms of "2 or more of a particular byte" works, except when that byte is a newline. Then you have to think of something that works for the entire line.
sed
is capable of handling several lines via its "pattern space" / "hold space" feature. But I feel that's too complicated. ;-)
May 16, 2013 at 13:42
1!
(match all except line 1), thus: sed '1!{/^$/d'}
.
Jan 28, 2016 at 19:51
sed
. Creating a file will essentially delete any existing file with the same name. sed '/^&/d' file.txt > otherfile.txt
will work.
No need for sed
. grep
will do:
grep .
(that's grep
, SPC, dot, that is match any line containing at least one character).
There's also:
tr -s '\n'
(squeeze any sequence of newline characters into one).
As noted by Chris, both are not equivalent because removing empty lines (like the first solution above and most other answers focus on here) is not the same as squeezing sequences of newline characters as requested in the case where the first line is empty as it only takes one leading newline character to make the first line empty.
\n{3,}
--> \n\n
.
If you wanted to keep a single blank line for any given sequence of blank lines you might do:
sed -e '/./b' -e :n -e 'N;s/\n$//;tn'
cat -s
) that actually accomplishes exactly what the question asked as I understand it. (And it's better than cat -s
because I can use sed -i
with it.)
What do you mean remove? remove duplicate (many blank line to one) or remove all?
If you want to remove duplicate, here is the method using sed:
sed '$!N; /^\(.*\)\n\1$/!P; D'
It simulates uniq
command.
The best choice is using awk
:
awk NF <filename>
sed
part of this works great! Recommending this one as the best answer.
Having seen @Bruce Ediger's answer sed
is not the best tool for that, since it is line based and treats \n
as the end-of-line character this gets complicated.sed
may well be the perfect tool for the job, still, here are some other options:
Perl
perl -ne 'print if /./' file.txt
or
perl -pe '$/=""; s/\n+/\n/;' file.txt
Thanks to @ruakh who made me go and read this:
$/
The input record separator, newline by default. This influences Perl's idea of what a "line" is. Works like awk's RS variable, including treating empty lines as a terminator if set to the null string (an empty line cannot contain any spaces or tabs). You may set it to a multi-character string to match a multi-character terminator, or to undef to read through the end of file. Setting it to "\n\n" means something slightly different than setting to "" , if the file contains consecutive empty lines. Setting to "" will treat two or more consecutive empty lines as a single empty line. Setting to "\n\n" will blindly assume that the next input character belongs to the next paragraph, even if it's a newline.
gawk/awk
awk '$1' file.txt
That will work for the example posted but as @Stephane Chazelas pointed out, it will also delete lines whose first field "looks like" 0
. This is more robust:
awk NF file.txt
perl -pe 's/\n+/\n/ file.txt
will do, the input record separator is irrelevant for this use.
perl -pe
or perl -ne
work line by line. \n+
will never match because it is only applied on a single line. That's why you need to either set $/
or use -0
ti slurp the file whole: perl -0pe 's/\n+/\n/' file
.
For most of these answers it is first necessary to remove trailing whitespace. Removing doubled up newlines removes all blank lines. (Think about this).
Literally interpreted the OP wants "all blank lines removed from a file if there are any repeated blank lines".
The typical user wants to "remove only duplicated blank lines".
To do this, strip trailing whitepace first, and pipe though cat -s
sed s/[[:space:]]*$// | cat -s
And yet this will not remove a superflous leading or trailing blank line.
To do so (with thanks to @cuonglm for part of the code)
sed 's|^[ \t]\+$||' your_filename | sed '$!N; /^\(.*\)\n\1$/!P; D'
Replace your_filename
with the actual filename.
Try sed -e 's#\\n\\n#\\n#g' input.file > output.file
using /
both as your field separator and part of your regex could be the problem.
If your file is using CRLF (DOS/Windows format) line-endings, try:
tr -s '\r' '\n'
echo -e 'one\r\n\r\n\r\n\rtwo'| tr -s '\r' '\n'
. The command tr
will translate all \r
to \n
and then will squeeze all \n
to just one. So, it works, not sure what to do with the fact that this apply to windows, not UNIX.
cat file | tr -s '\r' '\n'
returned the correct output.
Feb 4, 2020 at 1:48
^$
), not (escaped) double newlines within a line:aaa\n\nbbb
?