This chapter introduced few more special blocks and variables are that handy for processing multiple file inputs. These will show up in examples in coming chapters as well.
Next chapter will discuss use cases where you need to take decisions based on multiple input records.
Exercises
a) Print the last field of first two lines for the input files table.txt, scores.csv and fw.txt. The field separators for these files are space, comma and fixed width respectively. To make the output more informative, print filenames and a separator as shown in the output below. Assume input files will have at least two lines.
$ awk ##### add your solution here >table.txt< 42 -7 ---------- >scores.csv< Chemistry 99 ---------- >fw.txt< 0.134563 6 ----------
b) For the given list of input files, display all filenames that contain at or fun in the third field. Assume space as the field separator.
$ awk ##### add your solution here sample.txt secrets.txt addr.txt table.txt secrets.txt addr.txt table.txt
Processing multiple records
Often, you need to consider multiple lines at a time to make a decision, such as the paragraph mode examples seen earlier. Sometimes, you need to match a particular record and then get records surrounding the matched record. The condX{actionX} shortcut makes it easy to code state machines concisely, which is useful to solve such multiple record use cases. See softwareengineering: FSM examples if you are not familiar with state machines.
You might need to define a condition that should satisfy something for one record and something else for the very next record. awk does provide a feature to get next record, but that could get complicated (see getline section). Instead, you can simply save each record in a variable and then create the required conditional expression. The default behavior of uninitialized variable to act as 0 in numerical context and empty in string context plays a role too.
$ # match and print two consecutive records $ # first record should contain 'as' and second record should contain 'not' $ awk 'p ~ /as/ && /not/{print p ORS $0} {p=$0}' programming_quotes.txt Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it by Brian W. Kernighan $ # same filtering as above, but print only the first record $ awk 'p ~ /as/ && /not/{print p} {p=$0}' programming_quotes.txt Therefore, if you write the code as cleverly as possible, you are, $ # same filtering as above, but print only the second record $ awk 'p ~ /as/ && /not/; {p=$0}' programming_quotes.txt by definition, not smart enough to debug it by Brian W. Kernighan