Linux学习-awk使用
Posted 丢爸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux学习-awk使用相关的知识,希望对你有一定的参考价值。
awk–报告生成工具
[root@mail ~]# which awk
/bin/awk
[root@mail ~]# ll /bin/awk
lrwxrwxrwx. 1 root root 4 Apr 6 15:45 /bin/awk -> gawk
[root@mail scripts]# vim test.txt
this is a test
[root@mail scripts]# awk '{print $1}' test.txt
this
[root@mail scripts]# awk '{print $2}' test.txt
is
[root@mail scripts]# awk '{print $0}' test.txt
this is a test
[root@mail scripts]# awk '{print $1,$2}' test.txt
this is
#指定输出分隔符
[root@mail scripts]# awk 'BEGIN{OFS="#"}{print $1,$2}' test.txt
this#is
#输出中添加指定字符串
[root@mail scripts]# awk 'BGING{OFS="#"}{print $1,"hello",$2}' test.txt
this hello is
[root@mail scripts]# awk 'BEGIN{print "Line one\\nLine two\\nLine three\\n"}'
Line one
Line two
Line three
#-F指定分隔符
[root@mail scripts]# awk -F: '{print$1,$2}' /etc/passwd
root x
bin x
daemon x
adm x
...
awk变量
awk内置变量之记录变量
FS:Field separator,输入分隔符默认为空白字符
RS:Record separator,输入文本信息所使用的换行符
OFS:Ouput Field separator:输出分隔符
ORS:Output Row Separator:输出行分隔符
awk内置变量之数据变量
NR:The number of input records,awk命令所处理的记录数,如果有多个文件,这个数目会把处理的多个文件行统一计数
NF:Number of field,当前记录的field个数
FNR:与NR不同的是,FNR用于记录正在处理的行是当前这一个文件中被总共处理的行数
ARGV:数组,保存命令行本身这个字符串,如awk ‘{print $0}’ a.txt b.txt这个命令中,ARGV[0]保存awk,ARGV[1]保存a.txt
ARGC:awk命令的参数的个数
FILENAME:awk命令所处理的文件的名称
ENVIRON:当前shell环境变量及其值的关联数组,如awk ‘BEGIN{print ENVIRON[“PATH”]}’
[root@mail scripts]# awk 'BEGIN{print ENVIRON["PATH"]}'
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/apache/bin:/usr/local/mysql/bin:/usr/local/python3/bin:/root/bin
[root@mail scripts]# awk '{print NF}' test.txt
4
[root@mail scripts]# awk '{print $NF}' test.txt
test
awk用户自定义变量
gawk允许用户自定义自己的变量以便在程序代码中使用,变量名命名规则与大多数编程语言相同,只能使用字母、数字和下划线,且不能以数字开头,gawk变量名称区别字符大小写。
注:在awk中打印变量不需要使用$
#在脚本中赋值变量
[root@mail scripts]# awk 'BEGIN{var="this is a test page";print var}'
this is a test page
#在命令行中使用赋值变量
[root@mail scripts]# awk -v var="this is a main page" 'BEGIN{print var}'
this is a main page
prinf
printf format item1,item2…
注:
与print命令的最大不同是printf需要指定format
format用于指定后面的每个item的输出格式
printf语句不会自动打印换行符:\\n
format格式的指示符以%开头,后跟一个字符
%c:显示字符的ASCII码
%d,%i:十进制整数
%e,%E:科学计数法显示数值
%f:显示浮点数
%g,%G:以科学计数法的格式或浮点数的格式显示数值
%s:显示字符串
%u:无符号整数
%%:显示%自身
修辞符:
N:显示宽度
-:左对齐
+:显示数值符号
#通过数字显示宽度
[root@mail ~]# awk 'BEGIN{printf "%10s\\n","a"}'
a
[root@mail ~]# awk -F: '{printf "%5d\\n",$3}' /etc/passwd
0
1
2
3
... ...
算术运算符:
-x:负值
+x:转换为数值
x^y:次方
x**y:次方
x*y:乘法
x/y:除法
x+y:加法
x-y:减法
x%y:取余
[root@mail ~]# awk 'BEGIN{printf 5^2"\\n"}'
25
[root@mail ~]# awk 'BEGIN{printf 5**2"\\n"}'
25
[root@mail ~]# awk 'BEGIN{printf 5%2"\\n"}'
1
字符串连接
[root@mail ~]# awk 'BEGIN{a="hello";b="edison";printf a" "b "\\n"}'
hello edison
赋值运算符
+=
-=
*=
/=
%=
^=
**=
–
注:如果某模式为号,此时使用//会有语法错误,应以/[*]/来替代
[root@mail ~]# awk 'BEGIN{a=10;b=1;printf a+=b "\\n"}'
11
[root@mail ~]# awk 'BEGIN{a=10;b=1;printf a+=b"\\n"}'
11
[root@mail ~]# awk 'BEGIN{a=10;b=1;printf a-=b"\\n"}'
9
[root@mail ~]# awk 'BEGIN{a=10;b=1;printf a++"\\n"}'
10
[root@mail ~]# awk 'BEGIN{a=10;b=1;printf a*=b"\\n"}'
10
布尔表达式
x<y
x<=y
x>y
x>=y
x==y x是否等于y
x!=y x不等于y
x~y x匹配正则y
x!~y x不匹配正则y
subscript in array subscript在array数组中
表达式间的逻辑关系
&&
||
条件表达式
selector?if-true-exp:if-false-exp
[root@mail ~]# awk 'BEGIN{a=10;b=1;c = a>b ? a : b;printf c "\\n"}'
10
函数调用
function_name(para1,para2…)
awk模式
awk ‘pogram’ input-file1 input-file2…
其中的program为
pattern { action }
pattern { action }
…
常见的模式
Regexp:正则表达式,格式为/regular_expression/
expression:表达式,其值非0或为非空字符时满足条件,如:$1 ~ /foo/ 或$1 ==“tye”,用运算符(匹配)和!(不匹配)
Ranges:指定的匹配范围,格式为pat1,pat2
BEGIN/END:特殊模式,仅在awk命令执行前运行一次或结束前运行一次
Empty(空模式):匹配任意输入行
常见的Action
Expressions:
Control statements
Compound statements
Input Statements
Output statements
/正则表达式/:使用通配符的扩展集
关系表达式:可以用下面运算符表中的关系运行符进行操作,可以是字符串或数字的比较,如$2>%1选择第二个字段比第一个字段长的行
模式匹配表达式
模式模式:指定一个行的范围,该语法不能包括BEGIN和END模式
BEGIN:让用户指定在第一条输入记录被处理之前所发生的运行,通常可在这里设置全局变量
END:让用户在最后一条输入记录被读取之后发生的动作
#通过正则匹配只显示/etc/passwd文件中以r开头行的用户名
[root@mail ~]# awk -F: '/^r/{print $1}' /etc/passwd
root
rpc
rpcuser
#显示/etc/passwd文件中ID号大于等于500的用户名和ID号
[root@mail ~]# awk -F: '$3>=500 {print $1,$3}' /etc/passwd
postfix 2525
postdrop 2526
hadoop 2527
test 2528
vsftp 2529
nfsnobody 65534
sambauser 2530
#显示/etc/passwd中shell为bash的用户
[root@mail ~]# awk -F: '/bash$/{print $1,$7}' /etc/passwd
root /bin/bash
mysql /bin/bash
hadoop /bin/bash
test /bin/bash
sambauser /bin/bash
[root@mail ~]# awk -F: '$7~"bash$"{print $1,$7}' /etc/passwd
root /bin/bash
mysql /bin/bash
hadoop /bin/bash
test /bin/bash
sambauser /bin/bash
#查找uid为0,且shell为bash的用户
[root@mail ~]# awk -F: '$3==0,$7~"bash$"{print $1}' /etc/passwd
root
[root@mail ~]# awk -F: '$3==0,$7~"nologin"{print $1,$7}' /etc/passwd
root /bin/bash
bin /sbin/nologin
#打印表头
[root@mail ~]# awk -F: 'BEGIN{print "UserName Shell"}{printf "%-10s%-10s\\n",$1,$7}' /etc/passwd
UserName Shell
root /bin/bash
bin /sbin/nologin
... ...
#打印表头和表尾
[root@mail ~]# awk -F: 'BEGIN{print "UserName Shell"}{printf "%-10s%-10s\\n",$1,$7}END{print "End of the report"}' /etc/passwd
UserName Shell
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
... ...
End of the report
#awk条件判断语句
[root@mail ~]# awk -F: '{if ($1=="root") print $1,"is administrator";else print $1,"Common User"}' /etc/passwd
root is administrator
bin Common User
daemon Common User
... ...
[root@mail ~]# awk -F: '{if($1=="root") printf "%-15s:%s\\n",$1,"admin";else printf "%-15s:%s\\n",$1,"Common User"}' /etc/passwd
root :admin
bin :Common User
daemon :Common User
adm :Common User
... ...
#统计ID大于500的人数
[root@mail ~]# awk -F: -v sum=0 '{if ($3>=500) sum++} END{print "it has "sum" user id>500"}' /etc/passwd
it has 7 user id>500
#输出字段大于4个字符的信息--while
[root@mail ~]# awk -F: '{i=1;while(i<=NF) {if(length($i)>=4) {print $i} i++}}' /etc/passwd
root
root
/root
/bin/bash
... ...
#awk --for循环
[root@mail ~]# awk -F: '{for(i=1;i<=NF;i++) {if(length($i)>=4) print $i }}' /etc/passwd
root
root
/root
/bin/bash
... ...
#统计Shell的数量
[root@mail ~]# awk -F: '{shell[$NF]++}END{for(A in shell) {print A,shell[A]}}' /etc/passwd
/sbin/shutdown 1
/bin/bash 5
/sbin/nologin 26
/sbin/halt 1
/bin/sync 1
#统计tcp连接状态值
[root@mail ~]# netstat -tan | grep 'tcp' | awk '{foreign[$NF]++}END{for(i in foreign) {print i,foreign[i]}}'
ESTABLISHED 1
LISTEN 12
[root@mail ~]# netstat -tan | awk '/^tcp/{foreign[$NF]++}END{for(i in foreign) {print i,foreign[i]}}'
ESTABLISHED 1
LISTEN 12
#统计httpd服务器的客户端访问情况
[root@mail tye]# awk '{accessip[$1]++}END{for(i in accessip) {printf "%-18s %s\\n",i,accessip[i]}}' access_log
127.0.0.1 141350
192.168.0.105 62
192.168.88.1 326
::1 1
192.168.88.137 3
以上是关于Linux学习-awk使用的主要内容,如果未能解决你的问题,请参考以下文章
[Linux Shell学习系列十四]sed和awk-6.awk与Shell