awk
awk:一种编程语言。处理数据,文本方式为:从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行想要的操作,并把结果标准输出。
awk options BEGIN body_command END file
awk [参数] 'BEGING {awk——conmmand} '/patarm/{awk——conmmand}' END{awk——conmmand} file
列为域(每个域为字段),行为记录 $0表示整个记录
BEGIN区域:
BEGIN { awk-commands}
BEGIN区域的命令在body之前执行一次,打印报文头信息,以及用来初始化变量,是可选的。
body区域:
/pattern/{action}
body区域的命令每次输入一行文件就会执行一次,此区域没有任何关键字表示,只能用正则模式和命令。
END区域:
END { awk-commands}
END区域用于打印报文结尾信息,以及一些清理动作,在所有动作执行完才会执行END区域,END区域可以有一个或者多个,是可选的。
选项:
-f file:从指定文件中读取匹配条件等信息
-F :指定输入字段分隔符
-v :变量
内置变量:
ARGC :命令行参数个数
# [root@test1 ~]# awk -F: '/^root/ {print ARGC}' ./test/passwd
2
# [root@test1 ~]# awk -F: '/^root/ {print ARGC}' ./test/passwd ./test/123
3
ARGV :命令行参数数组排列
# [root@test1 ~]# awk 'BEGIN{print ARGV[0]}' ./test/passwd /etc/passwd
awk
# [root@test1 ~]# awk 'BEGIN{print ARGV[1]}' ./test/passwd /etc/passwd
./test/passwd
# [root@test1 ~]# awk 'BEGIN{print ARGV[2]}' ./test/passwd /etc/passwd
/etc/passwd
ENVIRON :
# awk -F: '/^root/{print ENVIRON[0]}' passwd
# awk 'BEGIN{for (i in ENVIRON) {print i"="ENVIRON[i];}}' #外部环境变量
FILENAME :当前输入文件的名称
# [root@test1 ~]# awk -F: '/^root/ {print FILENAME,$1}' ./test/passwd
./test/passwd root
FNR :匹配内容在源文件的行号
#[root@test1 ~]# awk -F: '{print FNR,$0}' ./test/c ./test/a
1 a b c d e # ./test/c
1 1 # ./test/a
2 2
3 3
4 4
NR :输出记录行号
# [root@test1 ~]# awk -F: '{print NR,$0}' ./test/c
1 a b c d e
# [root@test1 ~]# awk -F: '{print NR,$0}' ./test/c ./test/a
1 a b c d e
2 1
3 2
4 3
5 4
# awk -F: 'NR==1 {print $1}' passwd #第一行的第一列
FS :输入字段分隔符,默认为一个空格
# [root@test1 ~]# awk 'BEGIN{FS=":"} /^root/ {print $1}' ./test/passwd
root
OFS :输出字段分隔符
# [root@test1 ~]# awk -F: ' /^root/ {print $1,$2,$7}' ./test/passwd
root x /bin/bash
# [root@test1 ~]# awk -F: -v OFS=' ' ' /^root/ {print $1,$2,$7}' ./test/passwd
root x /bin/bash
RS :输入记录分隔符,默认一个换行符
# [root@test1 ~]# cat ./test/c
a b c d e
# [root@test1 ~]# awk -v RS=' ' '{print $0}' ./test/c
a
b
c
d
e
#此处的换行符为原换行符
ORS :输出记录分隔符
# [root@test1 ~]# awk -v RS=' ' '{print $0}' ./test/c | awk -v ORS=' ' '{print $0}'
a b c d e [root@test1 ~]#
NF :当前输入记录中字段(域)的数目
# [root@test1 ~]# awk -F: '/^root/ {print NF,$0}' ./test/passwd
7 root :x:0:0:root:/ root :/bin/bash #以":"分割,共七个域
# [root@test1 ~]# awk -F: '/^root/ {print NF,$(NF-1),$0}' ./test/passwd
7 /root root:x:0:0:root:/root:/bin/bash
OFMT :数字的输出格式
awk 'BEGIN{FS=":"} /root/{print OFMT}' passwd
%.6g
%.6g
RT :记录终止符
# awk -v RS='[0-9]+' '{s+=RT}END{print s}' file
RSTART :匹配第一个字符的索引 --->>> ???
# awk -F: '/bash$/ {print RSTART,$0}' ./test/passwd
0 root :x:0:0:root:/ root :/bin/bash
0 test1:x:1000:1000::/home/test1:/bin/bash
0 test2:x:1001:1001::/home/test2:/bin/bash
RLENGTH :匹配字符串长度
# echo "hello world" > file3
# awk 'match($0,/[a-z]+$/){print RSTART,RLENGTH}' file3
7 5
# 注:7表示world中w的索引,5表示world的长度(/[a-z]+$ 从后面匹配)
SUBSEP :字段用于分隔多个标在数组中的元素,默认"\034"
[root@test1 test]# awk '
> BEGIN {
> for (i = 1; i <= 2; i++)
> for (j = 1; j <= 3; j++)
> array[i,j] = i * j * 10
> for (x in array)
> print x, array[x]
> }'
21 20
22 40
23 60
11 10
12 20
13 30
[root@test1 test]# awk '
> BEGIN {
> SUBSEP = ":"
> for (i = 1; i <= 2; i++)
> for (j = 1; j <= 3; j++)
> array[i,j] = i * j * 10
> for (x in array)
> print x, array[x]
> }'
1:1 10
1:2 20
1:3 30
2:1 20
2:2 40
2:3 60
ARGIND :当前文件的ARGV索引正在处理中
# awk 'ARGIND==1 {a[$0]} ARGIND>1&&!($0 in a) {print $0}' a b
# 注:文件b包含文件a,此条打印出来的为文件b中除a文件之外的字符
IGNORECASE:不区分大小写[1|0]
# awk -F: 'BEGIN{IGNORECASE=1}/root/{print }' passwd
root:x:0:0:root:/root:/bin/bash
ROOT:x:3:4:adm:/var/adm:/sbin/nologin
operator:x:11:0:operator:/root :/sbin/nologin
格式化输出:
printf "FORMAT" ,item1,item2...
%c :显示字符的ASCII码
%d,%i :显示十进制整数
%e,%E :显示科学计数法数值
%f :显示浮点数
%g,%G:以科学计数法或浮点数显示数值
%s :显示字符串
%u :无符号整数
%% :显示%自身
printf :修饰符:
[.#] :第一个数字控制线是的宽度,第二个#表示小数点后精度, %3.1f
- :左对齐(默认右对齐) %-15s
+ :显示数值的正负符号 %+d
替换函数 gsub
# awk -F: '{gsub(/root/,"admin");print $0}' passwd
if 双重判断:&& || !
# awk '{if (NR <15 && $NF~"bash") print $0}' passwd
例
取单个字母
echo hello| awk '{print substr($1,1,1)}'
[root@test1 ~]# echo hello| awk '{print substr($1,1,1)}'
h
[root@test1 ~]# echo hello| awk '{print substr($1,2,1)}'
e
自定义变量
# awk -v var="hello world" '{print var}' passwd # password中n行,打印n个hello world
# awk -F: -v var="username: " 'NR==1 {print var,$1}' passwd
username: root
# awk -F: 'BEGIN{var="username: "} NR==1 {print var,$1}' passwd
username: root
# awk -F: -v var="username:" -v var1="user1" -v var="user2" 'NR==1 {print var,$1}' passwd
user2 root
# awk -F: 'BEGIN{var="username: ";var1="user1";var2="user2"} NR==1 {print var,$1}' passwd
username: root
正则匹配
# awk -F: '$5~/down/ {print $0}' passwd
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
# awk -F: '{if($5~"down") print $0}' passwd
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
# awk -F: '$NF~/bash/ {print $0}' passwd
root:x:0:0:root:/root:/bin/bash
# awk -F "[:/]" '$NF=="bash" {print $0}' passwd
root:x:0:0:root:/root:/bin/bash
# awk -F "[:/]" '$NF!~"bash" {print $0}' passwd
# awk -F: '$0 ~/(^mail|^root)/' passwd
root:x:0:0:root:/root:/bin/bash
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
统计password文本中的字母数量
# awk -F"[^[:alpha:]]" '{for (i=1;i<=NF;i++){(substr($0,i,1))~/[[:alpha:]]/ && array[substr($0,i,1)]++}}END{for (i in array){print array[i],i}}' passwd |sort -nr|head -3
10 x
6 o
6 a
统计password文本中的单词数量
# awk -F"[^[:alpha:]]" '{for (i=1;i<=NF;i++){$i~/[[:alpha:]]/ && array[$i]++}}END{for (i in array) {print array[i],i}}' password |sort -nr|head -5
31 x
28 sbin
22 nologin
13 var
10 bin
打印出password中的普通用户
# awk -F: '{if ($3>1000) print $1}' password
test2
user1
virtual
nfsnobody
求password文档中以:分割第三、四域之和
# awk -F: '{sum3+=$3;sum4+=$4}END{printf "第三域的和:%s\n第四 域的和:%s\n总和%+14s\n",sum3,sum4,sum3+sum4}' password
第三域的和:73375
第四域的和:73473
总和 146848
------------------------------------------------------------------------------------------------------- 返回目录