|
| 1 | +# Introduction |
| 2 | + |
| 3 | +## More about Patterns |
| 4 | + |
| 5 | +Recall from the Fundamentals concept, an AWK program is composed of **pattern-action pairs**. |
| 6 | + |
| 7 | +```awk |
| 8 | +pattern1 { action1 } |
| 9 | +pattern2 { action2 } |
| 10 | +... |
| 11 | +``` |
| 12 | + |
| 13 | +### What do we mean by "pattern"? |
| 14 | + |
| 15 | +The "pattern" is any AWK expression. |
| 16 | +The truthiness of the expression's result determines if the action is executed. |
| 17 | + |
| 18 | +### The Empty Pattern |
| 19 | + |
| 20 | +The pattern can be omitted. |
| 21 | +In this case, the action is performed for every record. |
| 22 | + |
| 23 | +We can print all the usernames in the passwd file. |
| 24 | + |
| 25 | +```sh |
| 26 | +awk -F: '{print $1}' /etc/passwd |
| 27 | +``` |
| 28 | + |
| 29 | +### Regular Expressions |
| 30 | + |
| 31 | +AWK can compare strings against regular expressions to obtain a boolean result. |
| 32 | + |
| 33 | +Use the `~` regex-matching operator to match a particular field. |
| 34 | +This operator takes a string as the left-hand operand and a regular expression as the right-hand operand. |
| 35 | +A regular expression literal is enclosed in `/` slashes. |
| 36 | + |
| 37 | +To find the users in the passwd file who log in with bash: |
| 38 | + |
| 39 | +```sh |
| 40 | +awk -F: '$7 ~ /bash/ {print $1}' /etc/passwd |
| 41 | +``` |
| 42 | + |
| 43 | +`!~` is the "regex does **not** match" operator. |
| 44 | + |
| 45 | +To match a regex against the current record, you can do `$0 ~ /regex/`. |
| 46 | +This is so common there is a shorthand: you can drop the `$0` and `~` and simply write `/regex/` |
| 47 | + |
| 48 | +```sh |
| 49 | +awk '/regex/' data.txt |
| 50 | +``` |
| 51 | + |
| 52 | +~~~~exercism/note |
| 53 | +Compare that AWK one-liner with the equivalent grep command |
| 54 | +
|
| 55 | +```sh |
| 56 | +grep 'regex' data.txt |
| 57 | +``` |
| 58 | +
|
| 59 | +AWK gives you a whole programming language without sacrificing succinctness. |
| 60 | +~~~~ |
| 61 | + |
| 62 | +We'll get more into GNU AWK's regular expression flavor in a further concept. |
| 63 | + |
| 64 | +### Expressions |
| 65 | + |
| 66 | +AWK expressions (arithmetic, logical, or otherwise) can be used as patterns. |
| 67 | + |
| 68 | +To extract all users with UID 1000 or above: |
| 69 | + |
| 70 | +```sh |
| 71 | +awk -F: '$3 >= 1000' /etc/passwd |
| 72 | +``` |
| 73 | + |
| 74 | +Recall that AWK's false values are the number zero and the empty string, and all other numbers or strings are true. |
| 75 | +Any expression that evaluates to a number or a string can be used as a pattern. |
| 76 | + |
| 77 | +### Functions |
| 78 | + |
| 79 | +Any [builtin][builtins] or [user-defined][] function can be used in an expression, and hence in the pattern. |
| 80 | +A couple of examples: |
| 81 | + |
| 82 | +```awk |
| 83 | +length($1) {print "first field is not empty"} |
| 84 | +``` |
| 85 | +```awk |
| 86 | +toupper(substr($1, 1, 1)) ~ /[AEIOU]/ {print "starts with a vowel"} |
| 87 | +``` |
| 88 | + |
| 89 | +### Constant Patterns |
| 90 | + |
| 91 | +A common AWK idiom is: |
| 92 | + |
| 93 | +```sh |
| 94 | +{ |
| 95 | + xyz() # some code that transforms each record |
| 96 | +} |
| 97 | +1 |
| 98 | +``` |
| 99 | + |
| 100 | +`1` is a truthy pattern with no associated action. |
| 101 | +This means "print the current record." |
| 102 | + |
| 103 | +[builtins]: https://www.gnu.org/software/gawk/manual/html_node/Built_002din.html |
| 104 | +[user-defined]: https://www.gnu.org/software/gawk/manual/html_node/User_002ddefined.html |
0 commit comments