This page lists which awk implementations support which features. Additions and corrections are very welcome.
Feature | POSIX awk | GNU awk 3.1.6 | Busybox awk 1.11.3 | mawk 1.3.3 | nawk (solaris 2.8) | /usr/xpg4/bin/awk (solaris 2.8) | tawk x.xx | FreeBSD? awk 20070501(apparently this is the "one true awk") | NetBSD? awk 20030729 | jawk 1.02 |
---|---|---|---|---|---|---|---|---|---|---|
{m,n} repetition in RE | yes | yes,with --re-interval or --posix | yes | no | no | yes | unknown | no | no | yes |
Special characters in RE (\w etc.) | no | yes (but not in POSIX mode) | yes | no | no | no | unknown | no | no | no |
using empty FS to split characters | no (undefined) | yes, but not in POSIX mode | yes | yes | no | no | unknown | no | no | yes |
FS can match the empty string | unknown? | no | yes | no | no | no | unknown | no | no | yes |
split() splits chars with empty sep | undefined | yes (both with // and "") | yes (extra field with //) | yes with "", no with // | no | no | unknown | yes with "", no with // | yes (extra field with //) | yes |
sub()/gsub() can replace the empty regex | unknown? | yes | yes | yes | only with o* (see sample code) | yes | unknown | yes | yes, but only with an implicit regex (see sample code) | yes |
using a regex for RS | no (undefined) | yes, even in POSIX mode! | yes | yes | no | no | unknown | no | no | no |
RT | no | yes, but not in POSIX mode | yes | no | no | no | unknown | no | no | no |
-v to pass values | yes | yes | yes | yes | yes | yes | unknown | yes | yes | yes |
ENVIRON array | yes | yes | yes | yes | yes | yes | unknown | yes | yes | yes |
gensub() | no | yes, but not in POSIX mode | yes | no | no | no | unknown | no | yes (no backrefs) | no |
strftime() | no | yes, but not in POSIX mode | yes | no | no | no | unknown | no | yes | no |
length(array) | no | yes (new in 3.1.5), but not in POSIX mode | no | no | no | no | unknown | yes! | yes | no |
asort() | no | yes, but not in POSIX mode | no | no | no | no | unknown | no | no | no |
FNR | yes | yes | yes | yes | yes | yes | unknown | yes | yes | no |
ARGV array | yes | yes | yes | yes | yes | yes | unknown | yes | yes | yes |
print (and possibly others?) in for definition | yes? | yes | no | no | yes | no | unknown | yes | yes | yes |
$0 contains the last record in the END block | yes? | yes | yes | yes | no | no | unknown | yes | no | no |
Feature | Test code # expected result if feature is supported |
---|---|
{m,n} repetition in RE | echo aaa|awk '/a{3}/' # aaa |
Special characters in RE (\w etc.) | echo 'a,b'|awk '/\<\w\W\w\>/' # a,b |
using empty FS to split characters | echo abc|awk -F '' '{print NF}' # 3 |
FS can match the empty string | echo aaba|awk -F 'b*' '{print NF}' # >2 |
split() splits chars with empty sep | echo abc|awk '{print split($0,a,"")}' # >1; also try with // |
sub()/gsub() can replace the empty regex (explicit) | echo abc|awk '{sub(//,"X")}1' # Xabc; also try with "" |
sub()/gsub() can replace the empty regex (implicit) | echo abc|awk '{sub(/o*/,"X")}1' # Xabc; also try with "o*" |
using a regex for RS | echo a4b|awk -v RS='[0-9]' 'NR==1' # a |
RT | echo a4b|awk -v RS='[0-9]' 'NR==1{print RT}' # 4 |
-v to pass values | awk -v foo=bar 'BEGIN {print foo}' # bar |
ENVIRON array | a=FOO awk 'BEGIN {print ENVIRON["a"]}' # FOO |
gensub() | echo aba|awk '{print gensub(/a/,"o",2)}' # abo |
gensub() with backrefs | echo aba|awk '{print gensub(/(a)/,"o\\1",2)}' # aboa |
strftime() | awk 'BEGIN{print strftime("%F %T",1)}' # 1970-01-01 00:00:01 |
length(array) | awk 'BEGIN{a[1]=10;a[2]=20;print length(a)}' # 2 |
asort() | awk 'BEGIN{a[1]="z";a[2]="a";asort(a);printf "%s %s\n",a[1],a[2]}' # a z |
FNR | echo a | awk '{print FNR}' # 1 |
ARGV array | awk 'BEGIN{print ARGV[1]}' foo # foo |
print (and possibly others?) in for definition | awk 'BEGIN{for(a=1;a<2;print){$0=a"foo";a++}}' # 1foo |
$0 contains the last record in the END block | echo foo | awk 'END{print}' # foo |
Another compatibility list can be found at shelldorado: