Awk
Since Awk reads the file sequentially, from the first to the last line, without external help (e.g. Tac) it can only figure whether a block of empty lines is at the end of the file when it actually reaches the end of the file.
What you can do is keep a variable with the empty lines (i.e., only newline characters, the default record separator RS
) and print those empty lines whenever you reach a non-empty line:
awk '/^$/{n=n RS}; /./{printf "%s",n; n=""; print}' file
I don't understand why there is a difference between print n
and printf n
.
print
appends the output record separator (ORS
, by default a newline) to the expression to be printed. Thus you would get an extra newline if you tried it. You could also write it with a single output statement as in
awk '/^$/{n=n RS}; /./{printf "%s%s%s",n,$0,RS; n=""}' file
To print the output (just as Awk did), choose either of
printf '%s\n' 'a' '' '.' '?.?+1,$d' ',p' 'Q' | ed -s file
printf '%s\n' 'a' '' '.' '?.?+1,$d' '%p' 'q!' | ex -s file
To directly apply the changes to the file, choose either of
printf '%s\n' 'a' '' '.' '?.?+1,$d' 'w' 'q' | ed -s file
printf '%s\n' 'a' '' '.' '?.?+1,$d' 'x' | ex -s file
To understand what's going on.
Shells strip trailing newline characters in command substitution.
printf '%s\n' "$(cat file)"
Mind that some shells will not handle large files and error with "argument list too long".
Inspired by this answer.
awk
– CodingNoob Aug 27 '21 at 19:59as long as it is empty
is an ambiguous statement because some people consider a line of blanks to be empty (as you apparently do) while others consider only a line that has no contents to be empty. So if/when you find yourself referring to any data as "empty" in future be sure to state what you mean by that. Most of the answer you have so far (e.g. all those that test^$
) will fail given an "empty" input line that contains blanks since we're all making different assumptions about what "empty" means. – Ed Morton Aug 27 '21 at 20:23