CLI tip 12: squeeze empty lines
awk
has a builtin feature to process input content paragraph wise (by setting RS
to an empty string). But, did you know that cat
, less
and grep
can also be used to squeeze empty lines?
cat -s
(and less -s
) will squeeze multiple empty lines in the input to a single empty line in the output. Here's an example:
$ cat ip.txt
hello
world
apple
banana
cherry
tea coffee
chocolate
$ cat -s ip.txt
hello
world
apple
banana
cherry
tea coffee
chocolate
Here's an example with empty lines at the start/end of the input:
$ printf '\n\n\ndragon\n\n\nunicorn\n\n\n'
dragon
unicorn
$ printf '\n\n\ndragon\n\n\nunicorn\n\n\n' | cat -s
dragon
unicorn
And here's a solution with awk
. Unlike the -s
option, this will completely remove empty lines at the start/end of the input.
$ awk -v RS= '{print s $0; s="\n"}' ip.txt
hello
world
apple
banana
cherry
tea coffee
chocolate
$ printf '\n\n\ndragon\n\n\nunicorn\n\n\n' | awk -v RS= '{print s $0; s="\n"}'
dragon
unicorn
The awk
solution would be easier to extend, given its programmable features. For example, two empty lines between the groups:
$ awk -v RS= '{print s $0; s="\n\n"}' ip.txt
hello
world
apple
banana
cherry
tea coffee
chocolate
And here's a surprising GNU grep
solution, with a customizable group separator:
# single empty line
$ grep --group-separator= -A0 '.' ip.txt
hello
world
apple
banana
cherry
tea coffee
chocolate
# double empty line
# empty lines at the start/end of the input are removed too
$ printf '\n\n\ndragon\n\n\nunicorn\n\n\n' | grep --group-separator=$'\n' -A0 '.'
dragon
unicorn
Video demo:
See also my CLI text processing with GNU Coreutils, CLI text processing with GNU awk and CLI text processing with GNU grep and ripgrep ebooks.