1. awk简介 -F fs or --field-separator fs -W posix -W re-interval or --re-inerval -W source program-text or --source program-text -W version or --version
2. awk命令格式和选项
3. 模式和操作
4. awk的环境变量
5. awk运算符
6. 记录和域
7. gawk专用正则表达式元字符
8. POSIX字符集
9. 匹配操作符(~)
10. 比较表达式
11. 范围模板
12. 一个验证passwd文件有效性的例子
13. 几个实例
14. awk编程
15. How-to
正文
1. awk简介
2. awk命令格式和选项
awk [options] 'script' var=value file(s)
awk [options] -f scriptfile var=value file(s)
指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。
-v var=value or --asign var=value
赋值一个用户定义变量。
-f scripfile or --file scriptfile
从脚本文件中读取awk命令。
-mf nnn and -mr nnn
对nnn值设置内在限制,-mf选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。
-W compact or --compat, -W traditional or --traditional
在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。
-W copyleft or --copyleft, -W copyright or --copyright
打印简短的版权信息。
-W help or --help, -W usage or --usage
打印全部awk选项和每个选项的简短说明。
-W lint or --lint
打印不能向传统unix平台移植的结构的警告。
-W lint-old or --lint-old
打印关于不能向传统unix平台移植的结构的警告。
打开兼容模式。但有以下限制,不识别:\x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符**和**=不能代替^和^=;fflush无效。
允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]。
使用program-text作为源代码,可与-f命令混用。
打印bug报告信息的版本。
3. 模式和操作
pattern {action} 如$ awk '/root/' test,或$ awk '$3 < 100' test
4. awk的环境变量
Table 1. awk的环境变量
变量 | 描述 |
$n | 当前记录的第n个字段,字段间由FS分隔。 |
$0 | 完整的输入记录。 |
ARGC | 命令行参数的数目。 |
ARGIND | 命令行中当前文件的位置(从0开始算)。 |
ARGV | 包含命令行参数的数组。 |
CONVFMT | 数字转换格式(默认值为%.6g) |
ENVIRON | 环境变量关联数组。 |
ERRNO | 最后一个系统错误的描述。 |
FIELDWIDTHS | 字段宽度列表(用空格键分隔)。 |
FILENAME | 当前文件名。 |
FNR | 同NR,但相对于当前文件。 |
FS | 字段分隔符(默认是任何空格)。 |
IGNORECASE | 如果为真,则进行忽略大小写的匹配。 |
NF | 当前记录中的字段数。 |
NR | 当前记录数。 |
OFMT | 数字的输出格式(默认值是%.6g)。 |
OFS | 输出字段分隔符(默认值是一个空格)。 |
ORS | 输出记录分隔符(默认值是一个换行符)。 |
RLENGTH | 由match函数所匹配的字符串的长度。 |
RS | 记录分隔符(默认是一个换行符)。 |
RSTART | 由match函数所匹配的字符串的第一个位置。 |
SUBSEP | 数组下标分隔符(默认值是\034)。 |
5. awk运算符
Table 2. 运算符
运算符 | 描述 |
= += -= *= /= %= ^= **= | 赋值 |
: | C条件表达式 |
|| | 逻辑或 |
&& | 逻辑与 |
~ ~! | 匹配正则表达式和不匹配正则表达式 |
< <= > >= != == | 关系运算符 |
空格 | 连接 |
+ - | 加,减 |
* / & | 乘,除与求余 |
+ - ! | 一元加,减和逻辑非 |
^ *** | 求幂 |
++ -- | 增加或减少,作为前缀或后缀 |
$ | 字段引用 |
in | 数组成员 |
6. 记录和域
7. gawk专用正则表达式元字符
\Y
匹配一个单词开头或者末尾的空字符串。
\B
匹配单词内的空字符串。
\<
匹配一个单词的开头的空字符串,锚定开始。
\>
匹配一个单词的末尾的空字符串,锚定末尾。
\w
匹配一个字母数字组成的单词。
\W
匹配一个非字母数字组成的单词。
\‘
匹配字符串开头的一个空字符串。
\'
匹配字符串末尾的一个空字符串。
8. POSIX字符集
待完善
9. 匹配操作符(~)
用来在记录或者域内匹配正则表达式。如$ awk '$1 ~/^root/' test将显示test文件第一列中以root开头的行。
10. 比较表达式
conditional expression1 ? expression2: expression3 |
例如:
$ awk '{max = {$1 > $3} ? $1: $3: print max}' test |
如果第一个域大于第三个域,$1就赋值给max,否则$3就赋值给max。
$ awk '$1 + $2 < 100' test |
如果第一和第二个域相加大于100,则打印这些行。
$ awk '$1 > 5 && $2 < 10' test |
如果第一个域大于5,并且第二个域小于10,则打印这些行。
11. 范围模板
范围模板匹配从第一个模板的第一次出现到第二个模板的第一次出现之间所有行。如果有一个模板没出现,则匹配到开头或末尾。如$ awk '/root/,/mysql/' test将显示root第一次出现到mysql第一次出现之间的所有行。
12. 一个验证passwd文件有效性的例子
$ cat /etc/passwd | awk -F: '\ NF != 7{\ printf("line %d,does not have 7 fields:%s\n",NR,$0)}\ $1 !~ /[A-Za-z0-9]/{printf("line %d,non alpha and numeric user id:%d: %s\n,NR,$0)}\ $2 == "*" {printf("line %d, no password: %s\n",NR,$0)}' |
cat把结果输出给awk,awk把域之间的分隔符设为冒号。
如果域的数量(NF)不等于7,就执行下面的程序。
printf打印字符串"line ?? does not have 7 fields",并显示该条记录。
如果第一个域没有包含任何字母和数字,printf打印“no alpha and numeric user id" ,并显示记录数和记录。
如果第二个域是一个星号,就打印字符串“no passwd”,紧跟着显示记录数和记录本身。
13. 几个实例
打印所有以模式no或so开头的行。
$ awk '/^(no|so)/' test |
如果记录以n或s开头,就打印这个记录。
$ awk '/^[ns]/{print $1}' test |
如果第一个域以两个数字结束就打印这个记录。
$ awk '$1 ~/[0-9][0-9]$/(print $1}' test |
如果第一个或等于100或者第二个域小于50,则打印该行。
$ awk '$1 == 100 || $2 < 50' test |
如果第一个域不等于10就打印该行。
$ awk '$1 != 10' test |
如果记录包含正则表达式test,则第一个域加10并打印出来。
$ awk '/test/{print $1 + 10}' test |
如果第一个域大于5则打印问号后面的表达式值,否则打印冒号后面的表达式值。
$ awk '{print ($1 > 5 ? "ok "$1: "error"$1)}' test |
打印以正则表达式root开头的记录到以正则表达式mysql开头的记录范围内的所有记录。如果找到一个新的正则表达式root开头的记录,则继续打印直到下一个以正则表达式mysql开头的记录为止,或到文件末尾。
$ awk '/^root/,/^mysql/' test |
14. awk编程
14.1. 变量
在awk中,变量不需要定义就可以直接使用,变量类型可以是数字或字符串。
赋值格式:
Variable = expression,如$ awk '$1 ~/test/{count = $2 + $3; print count}' test |
$ awk -F: -f awkscript month=4 year=2004 test |
$ awk '{$2 = 100 + $1; print }' test |
$ awk '$1 == "root"{$1 ="test";print}' test |
$ awk -F: '{IGNORECASE=1; $1 == "MARY"{print NR,$1,$2,$NF}'test |
联系客服