164

How do I remove empty/blank (including spaces only) lines in a file in Unix/Linux using the command line?

contents of file.txt

Line:Text
1:<blank>
2:AAA
3:<blank>
4:BBB
5:<blank>
6:<space><space><space>CCC
7:<space><space>
8:DDD

output desired

1:AAA
2:BBB
3:<space><space><space>CCC
4:DDD
kenorb
  • 6,779

9 Answers9

198

This sed line should do the trick:

sed -i '/^$/d' file.txt

The -i means it will edit the file in-place.

Eddie C.
  • 547
118

grep

Simple solution is by using grep (GNU or BSD) command as below.

  • Remove blank lines (not including lines with spaces).

    grep . file.txt
    
  • Remove completely blank lines (including lines with spaces).

    grep "\S" file.txt
    

Note: If you get unwanted colors, that means your grep is aliases to grep --color=auto (check by type grep). In that case, you can add --color=none parameter, or just run the command as \grep (which ignores the alias).


ripgrep

Similar with ripgrep (suitable for much larger files).

Remove blank lines not including lines with spaces:

rg -N . file.txt

or including lines with spaces:

rg -N "\S" file.txt

See also:

kenorb
  • 6,779
  • 8
    grep . seems to be the simplest solution. – Leo Mar 21 '18 at 21:36
  • The downside of grep . compared to the other solutions is that it will highlight all the text in red. The other solutions can preserve the original colors. Compare unbuffer apt search foo | grep . to unbuffer apt search foo | grep -v ^$ – wisbucky Apr 25 '19 at 23:09
  • 3
    @wisbucky You see colors, because grep is aliased to grep --color=auto on your system (check by: type grep). You can run it as \grep or use --color=none parameter. – kenorb Apr 25 '19 at 23:26
  • @kenorb If you use grep --color=none ., you will get all white text, which overrides the color formatting of the original command (example: apt search foo) – wisbucky Apr 26 '19 at 02:01
  • grep . will match lines containing only spaces, which the OP says is not desired. – Jim L. Jul 19 '19 at 21:53
  • @JimL. A dot (.) in grep matches any character, so it'll print all non-empty lines. Even the lines with a single empty space are going to be printed. – kenorb Jul 20 '19 at 14:50
  • Yes, and the OP wishes lines containing only spaces to be removed. – Jim L. Jul 20 '19 at 20:05
  • @JimL. I've improved answer with the solution removing lines with spaces. – kenorb Jul 22 '19 at 09:08
  • Actually, I think none of the other answers providing what OP requested (exempt Steven one). – kenorb Jul 22 '19 at 09:33
37
sed '/^$/d' file.txt

d is the sed command to delete a line. ^$ is a regular expression matching only a blank line, a line start followed by a line end.

Kamil Kisiel
  • 12,304
  • This command does not produce the same output as OP requested (it produces 5 lines, not 4). – kenorb Jul 22 '19 at 09:31
  • 1
    You likely need sed '/^[[:space:]]*$/d' file.txt. Credits to https://stackoverflow.com/a/16414489/123897 – jpbochi Sep 07 '23 at 16:19
23

You can use the -v option with grep to remove the matching empty lines.

Like this

grep -Ev "^$" file.txt
jdabney
  • 331
  • 5
    I don't believe you need the -E, at least not with GNU grep, but apart from that I'm so pleased to see this done with grep! It's what I reach for in preference to sed, every time; in-line filters seem to me to be better than in-line editors. – MadHatter Mar 28 '11 at 22:45
  • If you want to skip the commented and blank lines, especially while dealing with conf files use grep -Ev '^#|^$' file.txt – Govind Kailas Mar 07 '19 at 04:11
  • 1
    grep (GNU grep) 3.4 requires -E if you are using @GovindKailas' command – Yet Another User Aug 15 '20 at 04:07
20

Here is an awk solution:

awk NF file.txt

With Awk, NF only set on non-blank lines. When this condition match, Awk default action is to print the whole line.

kenorb
  • 6,779
Zombo
  • 1
9

To remove empty lines, you could squeeze new line repeats with tr:

cat file.txt | tr -s '\n' '\n'
siddhadev
  • 191
2

xargs if you dont mind stripping leading whitespace

$ docker run -it --rm alpine sh
/ # cat <<eof > /tmp/file
> one
>
>   two
> three
>
>
>   four
> eof
/ # cat /tmp/file
one

  two
three


  four
/ # cat /tmp/file | xargs -n1
one
two
three
four
1

Ex/Vim

Here is the method using ex editor (part of Vim):

ex -s +'v/\S/d' -cwq test.txt

For multiple files (edit in-place):

ex -s +'bufdo!v/\S/d' -cxa *.txt

Note: The :bufdo command is not POSIX.

Without modifying the file (just print on the standard output):

cat test.txt | ex -s +'v/\S/d' +%p +q! /dev/stdin
kenorb
  • 6,779
1

For me @martigin-heemels command was throwing error this fixed it (ie a dummy param to i),

sed -i '' '/^$/d' file.txt