Insert newline before each line matching a pattern unless the previous line is already empty
You could store the previous line in the hold space:
sed '
/^pattern/{
x
/./ {
x
s/^/\
/
x
}
x
}
h'
It would be more legible with awk
though:
awk '!previous_empty && /pattern/ {print ""}
{previous_empty = $0 == ""; print}'
Like the GNU implementations of sed
has a -i
option for in-place editing, the GNU implementation of awk
as -i inplace
for that.
But how do I determine the previous line, of a matching pattern, in the first place?
Umm... perhaps this will work.
Using grep
and the -B
switch:
-B num, --before-context=num
Print num lines of leading context before each match. See
also the -A and -C options.
Consider this infile:
cat infile
foo
bar
baz
Now, if I grep
for bar
, the previous line should be empty:
if [[ $(grep -B 1 'bar' infile | head -1) == "" ]]; then echo "line is empty"; fi
line is empty
As opposed to using grep
on baz
, where the previous line is not empty:
if [[ $(grep -B 1 'baz' infile | head -1) == "" ]]; then echo "line is empty"; fi
<no output>
Another way with sed
:
sed -e 'tD' -e '$!N;/.\npattern/s/\n/&&/;:D' -e 'P;D' infile
This was explained in detail here: it's basically an N;P;D
cycle where we account for the newlines we edit in, so each time the script inserts a \n
ewline it executes only P
and D
without N
so as to always have only two lines in the pattern space.