I'm running a cron job which should get only the last result of iostat -d 1 2. This requires some parsing: What is the simplest way to get the last set of non-empty lines from standard input to standard output if the length of each set is unknown?

Bad/non-working solutions:

  • tail since I'd still need to count the number of lines in the last set. iostat -d 1 2 | tail -$(echo "$(iostat -d 1 2 | wc -l) / 2" | bc) depends on equal set sizes.
  • split/csplit since they output to file, and keep the useless part of the data.
  • iostat -d 1 2 | sed '1,/^$/d' | sed '1,/^$/d' works only in this special case, since it gets the third set of non-empty lines, but also includes any trailing newlines.
  • iostat -d 1 2 | tac | sed '1,/^$/d' | sed '/^$/q' is a slightly better hack: Reverse and print the first set. However, since iostat outputs an empty line at the end, we first remove that then print until the next empty line in the reversed output. Other commands might output any number of newlines at the end, so it's not a general solution. Reverse again if you want to keep the original sequence.
  • grep -P with \Z seems to only detect EOL, not EOF.

3 Answers 3


You can use awk's paragraph mode (when RS is the empty string). That way each "set" is one record and you can easily print out the last one.

iostat -d 1 2 | awk -vRS= 'END{print}'
  • +1, Just Works(TM). To avoid problems with more empty lines, maybe RS="\n\n+" would be useful?
    – l0b0
    Commented Mar 17, 2011 at 10:53
  • 3
    more efficient to put the RS assignment in the BEGIN block. Commented Mar 17, 2011 at 10:56
  • 3
    Better make that awk -vRS= 'END{print}'. First, because the "\n\n" version will print an empty record if there are more than two blank lines at the end of the input. Second, because some versions of awk don't allow RS to be more than one character. An empty RS means “paragraph mode” where any sequence of two or more newlines separate records, and that's required by POSIX. Commented Mar 17, 2011 at 20:23

perl -00 is a good way to read one paragraph at a time, so the last paragraph is:

perl -00 -ne '$para = $_; END {print $para}'

With sed:

sed '/^$/{$!{N;/\n$/D;s/.//;$!h;$p;d};};//!{H;1h;$!d};$x' infile

this should print the last set of non-empty lines without any leading/trailing empty lines.

iostat -d 1 2 | sed '/^$/{       # if the line is empty
$!{                              # and if it's not the last line
N                                # then pull in the next line
/\n$/D                           # if also empty, delete up to \n, restart cycle
s/.//                            # otherwise delete leading \newline 
$!h                              # copy over hold space if not last line
$p                               # or print pattern space if last line
d                                # then delete pattern space
//!{                             # if the line isn't empty
H                                # append it to hold space
1h                               # if it's the first line, overwrite hold space
$!d                              # if it's not the last line, delete it
$x                               # on the last line, exchange buffers

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .