分类: LINUX
2010-11-30 14:49:49
Awk的基本用法总结
1. awk的命令格式总结
从脚本位置分,可以分为两大类:
awk [option] 'script' file
awk [option] -f scriptfile file
从具体格式分:
awk 'pattern' filename
awk 'pattern' {action} filename
awk 'pattern' {action} filename
awk的命令处理过过程:
每次读取一行,默认模式不匹配的动作时不打印,一旦匹配上以后就是按指定的动输出,如果没有动作那么就是打印这一行。如果没有模式语句,默认是对所有行执行动作语句。
2. awk的命令选项
awk的命令选项倒不少的,不过尝用的也就-f-v-F三个选项,注意下这几个就可以了。
-F fs or --field-separator fs
指定输入文件折分隔符,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平台移植的结构的警告。
-W posix
打开兼容模式。但有以下限制,不识别:\x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符**和**=不能代替^和^=;fflush无效。
-W re-interval or --re-inerval
允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]。
-W source program-text or --source program-text
使用program-text作为源代码,可与-f命令混用。
-W version or --version
打印bug报告信息的版本。
3. awk的正则表达式
awk支持通用的正则表达式和自己特有的正则表达式,通用的我就列举下,不做细致的解释了。
通用的:
^ ,$ ,. ,* ,+ ,? ,[] ,[^] ,a|b ,(ab),+ ,&
特有的:
A{m},A{m,},A{m,n} 这个和grap,sed的一样,不过这里不用\来转义了
\y 匹配一个单词开头或者末尾的空字符串
\B 匹配单词内的空字符串
\< 铆钉单词的开头
\> 锚定单词的结尾
\w 匹配一个字母数字组成的单词
\W 和\w相反
\' 匹配字符串开头的一个空字符串
\' 匹配字符串末尾的一个空字符串
注意:不是所有的都可以的用的,这个根据自己的awk类型,想{}和最后一个\'我怎么都没有试出来,不知道什么原因呢。
4. awk的模式和动作说明
模式控制awk对输入的文件行所做的操作,和sed中的模式类似,相当于判断和匹配之意。
例如:
awk '/alibaba/' file #找出所有含有alibaba的行。
awk ' $1~/alibaba/' file #打印每行第一个域匹配上alibaba的行
awk '$3>50' file
模式可以是以下任意一个:
/正则表达式/:使用通配符的扩展集。
关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符串或数字的比较,如$2>%1选择第二个字段比第一个字段长的行。
模式匹配表达式:用运算符~(匹配)和~!(不匹配)。
模式,模式:指定一个行的范围。该语法不能包括BEGIN和END模式。
BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。
END:让用户在最后一条输入记录被读取之后发生的动作
动作:
就是花括号内的句子,一般用分号分隔,也可以用换行符分隔.
Pattern{action ;action;}
Pattern{
Action
Action
}
至于动作就相当多了,在后面的awk编程,基本上都是在动作中完成的。主要有:
变量或数组赋值
输出命令
内置函数
控制流命令
5. 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)。 |
6. awk的运算符:
下表基本涵盖了所有用到的运算符,包括:赋值,关系,逻辑,条件
运算符 | 描述 |
= += -= *= /= %= ^= **= | 赋值 |
?: | C条件表达式 |
|| | 逻辑或 |
&& | 逻辑与 |
~ ~! | 匹配正则表达式和不匹配正则表达式 |
< <= > >= != == | 关系运算符 |
空格 | 连接 |
+ - | 加,减 |
* / & | 乘,除与求余 |
+ - ! | 一元加,减和逻辑非 |
^ *** | 求幂 |
++ -- | 增加或减少,作为前缀或后缀 |
$ | 字段引用 |
in | 数组成员 |
7. 经典的password有效性的例子
$ 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”,紧跟着显示记录数和记录本身。 |
8. 举例
条件判断:
root@localhost:~#awk -F: '{max=($3 == $4&&$3==86) ?"yes":"no";print max}' password
模板匹配:
root@localhost:~#awk '$4~/86/{print "The group id is: "$4"."}' password
root@localhost:~#awk -F: '$3>500{print $0}' passwd
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
赋值:
awk '$3=='tao''{$3="goodboy"};print}' file
awk '/alibaba/{$8+=10;pinr $8}' file
awk '/alibaba/{print $8+10}' file
awk '$5!=""{$5="hello"; print}' test