1 什么是awk awk不仅是一个文本处理命令,它更是一个编程语言.可处理列,不影响原文件。
2 awk简单用法
$ awk -F: '{print $1}' /etc/passwd
$ awk -F: '{print $1,$3}' /etc/passwd
$ awk -F: '{print $1 "|" $3}' /etc/passwd
$ awk -F: '/root/{print $1 "|" $3}' /etc/passwd
$ awk -F: '/^root/' /etc/passwd
$ awk -F: -f test.awk /etc/passwd
3 awk脚本语法
awk 'BEGIN {actions}
/pattern1/{actions}
......
/patternN/{actions}
END {actions} ' input_file
1) 其中BEGIN{actions}和END{actions}是可选的,注意BEGIN和END都是大写字母。
2) awk_script可以由一条或多条awk_cmd组成,每条awk_cmd各占一行。
3) awk_cmd中的/pattern/和{actions}可以省略,但不能同时省略;/pattern/省略时表示对所有的输入行执行指定的actions;{actions}省略时表示打印整行。
4 awk执行过程
①如果存在BEGIN,awk首先执行它指定的actions
②awk从输入中读取一行,称为一条输入记录
③awk将读入的记录分割成数个字段,并将第一个字段放入变量$1中,第二个放入变量$2中,以此类推;$0表示整条记录;字段分隔符可以通过选项-F指定,否则使用缺省的分隔符。
④把当前输入记录依次与每一个awk_cmd中pattern比较:如果相匹配,就执行对应的actions;如果不匹配,就跳过对应的actions,直到完成所有的awk_cmd
⑤当一条输入记录处理完毕后,awk读取输入的下一行,重复上面的处理过程,直到所有输入全部处理完毕。
⑥awk处理完所有的输入后,若存在END,执行相应的actions
⑦如果输入是文件列表,awk将按顺序处理列表中的每个文件。
5 示例
打印ip
$ ifconfig | awk '/inet addr/{ print $2 }' | awk -F: '{ print $2 }'
$ ifconfig | awk '/inet addr/{ print $2 }' | awk -F: 'BEGIN {print "begin.."}{ print $2 }' END{print "end..."}
6 模式匹配
1) 使用正则表达式
2) 使用布尔(比较)表达式,表达式的值为真时执行相应的操作(actions)
表达式中可以使用变量(如字段变量$1,$2等)和/rexp/
表达式中的运算符有
关系运算符: < > <= >= == !=
匹配运算符: ~ !~
x ~ /rexp/ 如果x匹配/rexp/,则返回真;
x !~ /rexp/ 如果x不匹配/rexp/,则返回真。
$ awk '$1 > 20 {print $0}' test.in
$ awk '$2 ~ /^6/ {print $0}' test.in
3) 复合表达式:&&( 逻辑与)、||( 逻辑或)、!( 逻辑非)
expr1 && expr2 两个表达式的值都为真时,返回真
expr1 || expr2 两个表达式中有一个的值为真时,返回真
!expr 表达式的值为假时,返回真
$ awk '($1<20)&&($2~/^6/){print $0}' test.in
$ awk '($1<20)||($2~/^6/){print $0}' test.in
$ awk '!($2 ~ /^6/){print $0}' test.in
$ awk '/^#/ && /#$/{ print }'test.in
注:表达式中有比较运算时,一般用圆括号括起来
7 字段分隔符
awk中的字段分隔符可以用-F选项指定,缺省是空格
awk'{print $1}' test.in
awk –F:' {print $1}' test.in
表示可以是空格或者:分隔
awk -F'[ :]'' {print $1}' test.in
8 重定向与管道
$ awk '{print $1, $2 > "output"}' test.in
$ awk 'BEGIN{"cal" | getline a; print a}'
9 更多awk
1) 变量
内部变量 awk '{print NR,$0}' #给文件加上行号
自定变量
2)函数
内置函数
自定义函数
awk' { print sum($1,$2) } function sum(x,y) { s=x+y; return s }' grade.txt
3)数组
$ awk 'BEGIN { print split("123#456",arr,"#") ; for (i in arr) { print arr[i] } }'