This is an old revision of the document!
Awk
General Information
AWK is a pattern scanning and processing language. Gawk is the GNU Project's implementation of the AWK programming language.
In most cases, awk is a symlink to gawk.
Checklist
- Distro(s): Any
- Software: awk/gawk installed
General Awk Variables
- -F“:” ⇒ Set the field seperator to colon (:), instead of spaces (default).
- This can be set to any character
- $0 ⇒ The entire line (excluding new line at the end)
- $1 - $number ⇒ The fields
- NF ⇒ Number of fields on the current line
- NR ⇒ Current line number
Gsub
gawk's gsub string function matches and replaces regular expressions. This can replace a grep | sed combination.
~$ echo -e "Hello, friend.\nHello, how are you?\nI am fine." | gawk 'gsub(/Hello/,"Goodbye")' Goodbye, friend. Goodbye, how are you?
Notice that the last line “I am fine.” is not displayed at all because it doesn't match the regex. (Hello)
Number Comparison
Bash doesn't have a really good way to compare floating point numbers. (Such as version numbers) This can be done very well with gawk.
Check to see if VERSION is >= to 3.5.3
VERSION=4.3.0 echo | gawk -v n1=${VERSION} -v n2=3.5.3 '{if (n1>=n2) print ("true"); else print ("false");}' true
Print Line After Match
Search for a regex string and print the line AFTER the match.
awk '/mystring/ { getline; print }'
Print Line Before Match
This trick allows you to search for a regex string, and print the line BEFORE the match.
FreeIPA Example: I want to get only enabled account usernames.
- Find users and account disabled status
/usr/bin/ipa user-find --sizelimit=0 --all | grep -E "(User login|Account disabled)" User login: rjones Account disabled: False User login: sanderson Account disabled: True
- Narrow it down to just usernames and True/False values
/usr/bin/ipa user-find --sizelimit=0 --all | grep -E "(User login|Account disabled)" | awk '{print $3}' rjones False sanderson True
- Add in the awk magic that will display ONLY the username with “False” after it (Not Disabled)
/usr/bin/ipa user-find --sizelimit=0 --all | grep -E "(User login|Account disabled)" | awk '{print $3}' | awk '/False/ { print x }; { x=$0 }' rjones
Explanation
- If the current line matches the regular expression “False” (“/False/”), then
- Print the value of x (“{ print x }”).
- Next, store the current line in the variable “x” (“{ x=$0 }”) (Always do this; Does not matter if it matches)
- This has the effect of making the previous line available when evaluating the next line.
- Note: This will not work if the very first line matches the pattern, as x will not contain any lines yet.