Skip navigation

Let’s say I’ve got a bunch of data i want to review one segment at a time.  My typical way of going through and doing something to many things in sequence would involve a for or while loop.  For the moment, consider a file named ‘stuff’ that contains a filename and a particular phrase on each line.  I want to see what lines in each filename match that particular phrase.  There could be many more than one, so I want to be able to separate the lines and phrases.  So, here’s how I’d typically go about that. As a note, even though these are shown across multiple lines, when this was originally done, they were one-liners (as evidenced by the ‘;’ at the end of each line).  I have broken them up into multi-line commands for ease of reading.

host> awk '{print $1 " " $2}' stuff | while read file phrase; > do echo === ${phrase}: $file ===; > grep $phrase $file; > done

This works if ‘stuff’ has only a few lines in it, but the output is unwieldy when the total number of lines gets above a couple dozen.  Also, with all the lines together, I can’t just focus on each discreet chunk of data on it’s own.  So, I want to pause the output and clear the screen before each chunk of output is shown.  The easiest way of doing the clearing is using ‘clear’.  The easiest way to do the pausing is using ‘read’.  Here’s my first shot at doing this:

host> awk '{print $1 " " $2}' stuff | while read file phrase; > do clear; > echo === ${phrase}: $file ===; > grep $phrase $file; > read foo; > done

This did the clearing just fine, but did not pause.  It turns out the ‘read foo’ statement inside the ‘while’ loop was noticing the input and acknowledging that.  So, I needed to tell the ‘read foo’ to read only from STDIN.  Here’s the update for doing that:

host> awk '{print $1 " " $2}' stuff | while read file phrase; > do clear; > echo === ${phrase}: $file ===; > grep $phrase $file; > read -u 1 foo; > done

And this did exactly what I wanted.