shell_05变量名、意义
变量名 意义
$n 当前记录的第n个域,域间由FS分割
$0 记录的所有域
ARGC 命令行参数的数量
ARGIND 命令行中当前文件的位置(以0开始标号)
ARGV 命令行参数的数组
CONVFMT 数字转换格式
ENVIRON 环境变量关联数组
ERRNO 最后一个系统错误的描述
FIELDWIDTHS 字段宽度列表,以空格键分割
FILENAME 当前文件名
FNR 浏览文件的记录数
FS 字段分隔符,默认是空格键
IGNORECASE 布尔变量,如果为真,则进行忽略大小写的匹配
NF 当前记录中的域数量
NR 当前记录数
OFMT 数字的输出格式
OFS 输出域分隔符,默认是空格键
ORS 输出记录分隔符,默认是换行符
RLENGTH 由match函数所匹配的字符串长度
RS 记录分隔符,默认是空格键
RSTART 由match函数所匹配的字符串的第1个位置
SUBSEP 数组下标分隔符,默认值是/034
netstat -ntulp |grep -v "Active" |grep -v "Proto"|sed 's////:/g' |sed "s//./:/g"| sed "s/fe80/:/://g" |awk -F':| +' '{print $1"/t"$8"/t"$13"/t"$15"/t"$16}' |head -30
awk的概述:
awk是一种编程语言,软件级别等同于bash,主要用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk的处理文本和数据的方式是这样的,它逐行扫描文件,默认从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕),如果没有指定模式,则所有被操作所指定的行都被处理。awk分别代表其作者姓氏的第一个字母。因为它的作者是三个人,分别是Alfred Aho、Brian Kernighan、Peter Weinberger。gawk是awk的GNU版本,它提供了Bell实验室和GNU的一些扩展。下面介绍的awk是以GNU的gawk为例的,在linux系统中已把awk链接到gawk,所以下面全部以awk进行介绍。
awk命令两种使用方式:
1)命令模式
awk [options] 'commands' file(s)
command 部分:/范围说明/{awk命令语句1;awk命令语句2;}
范围说明部分可以是BEGIN、END、逻辑表达式或者为空
awk命令语句间用分号间隔
引用shell 变量需用双引号引起
option 部分
-F 定义字段分割符号
2)脚本模式
awk [options] -f scriptfile file(s)
特点:
awk脚本是awk命令的清单
命令需要用分号间隔
#号开头的是注释行
字段及分割
awk 用$1,$2,$3...$n等的顺序形式表示files中每行以间隔符号分割的各列的不同字段
$0表示行本身
awk默认以空格符为间隔符号将每行分割为单独的字段,也可以使用awk内置变量FS定义间隔符号
awk 使用option中的-F参数定义默认间隔符号
NF变量表示当前记录的字段数(列数)
$NF 最后一列
$(NF-1) 倒数第二列
FNR/NR 行号
FILENAME 文件名
"/t" 制表符
RS 换行符
"" 打印字符串
# awk 'BEGIN {FS=":"} {print $1}' /etc/passwd
$ head -5 /etc/passwd > passwd
$ awk -F':' '{print FILENAME,FNR,NF,$1,$2,$3,$4,$5,$6,$7,"/t"$0}' ./passwd
./passwd 1 7 root x 0 0 root /root /bin/bash root:x:0:0:root:/root:/bin/bash
./passwd 2 7 bin x 1 1 bin /bin /sbin/nologin bin:x:1:1:bin:/bin:/sbin/nologin
./passwd 3 7 daemon x 2 2 daemon /sbin /sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin
./passwd 4 7 adm x 3 4 adm /var/adm /sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
./passwd 5 7 lp x 4 7 lp /var/spool/lpd /sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
打印所有行
$ cat passwd
$ awk -F':' '{print $0}' passwd
$ awk -F':' '{print}' passwd
取倒数第一列和倒数第二列
$ head -1 passwd |awk -F':' '{print $NF,$(NF-1)}'
/bin/bash /root
换行符(默认处理一行后才换行)
$ head -1 passwd |awk -F':' '{print $NF RS $(NF-1)}'
/bin/bash
/root
$head -1 passwd | awk 'BEGIN {FS=":"} {print $NF RS $(NF-1)}'
一次指定多个分隔符
$ awk -F':|/' '{print NF}' passwd
$ awk -F'[:/]' '{print NF}' passwd
$ ifconfig eth0|grep Bcast|awk -F':| +' '{print $4}'
$ifconfig eth0 |grep Bcast | awk -F" " '{print $2}'|awk -F":" '{print $2}'
定址:
1)关键字
BEGIN :表示在程序开始前执行
END :表示所有文件处理完后执行
操作流程:
#/bin/awk -f
BEGIN {} --读前处理(读取目标文件)
{} --行处理
END {} --读后处理
打印标题和结尾信息
$ awk -F':' 'BEGIN {print "user/tpasswd/thome"RS"----------------------"} ; {print $1"/t"$2"/t"$(NF-1)} ; END {print "<-----------END---------->"}' passwd
user passwd home
----------------------
root x /root
bin x /bin
daemon x /sbin
adm x /var/adm
lp x /var/spool/lpd
<-----------END---------->
2)正则表达式
$ awk '/root/ {print $0}' /etc/passwd --使用普通字符定位
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
$ awk '$0 ~ /^root/ {print $0}' /etc/passwd --使用正则表达式定位
root:x:0:0:root:/root:/bin/bash
$ awk '/^[rR]oot|^[bB]in/ {print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
# awk -F':' '/^[rR]oot|^[bB]in/ {print $1}' passwd
使用正则表达式精确定位
$ awk -F':' '$2=="" {print $0}' /etc/passwd
$ awk -F':' '$2=="" {print $0}' /etc/shadow --查看用户中有无空密码的
$ awk -F':' '$7 ~ /bash$/ {print $0}' /etc/passwd
$ awk -F':' 'NR>=5 && NR<=10 {print $0}' /etc/passwd
$ awk '/^root/,/^uucp/ {print $0}' /etc/passwd
3)逻辑表达式
例如:NR>40
例如:if ( $2>50) { print $3 }
逻辑表达式:
==(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)、<=(小于等 于)
~(匹配于)和!~(不匹配于)
!(非)、&&(与)、||(或)、和括号()
awk -F: 'NR<10 && NR>3 {print $0} ' /etc/passwd --与
awk -F: 'NR==10 || NR==3 {print NR,$0} ' /etc/passwd
--或
awk -F: '!(NR<40) {print NR,$1}' /etc/passwd --取反
awk -F: '$3>=500 && $3 <=60000 {print $3,$1}' /etc/passwd
--打印普通用户
awk -F: 'NR%2==0 {print NR,$0}' /etc/passwd -- 取偶数
awk -F: 'NR%2!=0 {print NR,$0} ' /etc/passwd --打印奇数行
awk -F: 'NR%2==1 {print NR,$0}' /etc/passwd
awk -F":" 'BEGIN {print "user_UID/tusername/t"RS"-------------------"}; ($3>=500 && $3<=60000) {print $3"/t","/t"$1} ; END {print "--------------------"}' /etc/passwd
awk的流程控制
if
for
while
if(expr1) action
if(expr1) action2;else aciton2
if(expr1) action1;else if(expr2);else
# awk -F: '{if($3>500) print $1,$3,"普通用户"}' /etc/passwd
# awk -F: '{if($3>500) print $1,$3,"普通用户";else print $1,$3,"不是普通用户"}' /etc/passwd
# awk -F: '{if($3==0) print $1,$3,"管理员";else if($3<500) print $1,$3,"系统用户";else print $1,$3,"普通用户"}' /etc/passwd
for
# awk 'BEGIN {for(i=0; i<=10; i++) print i}'
while
# awk 'BEGIN {i=0;while(i<=5) {print i;i++}}'
# awk 'BEGIN {i=0;while(i<=5) {print"service",i,"start";i++}}'
#循环的控制:
break --条件满足的时候中断循环
continue --条件满足的时候跳过循环
# awk 'BEGIN {i=0;while(i<=5) {i++;if(i==3) continue; print i}}'
# awk 'BEGIN {i=0;while(i<=5) {i++;if(i==3) break; print i}}
用netstat -ntl 截取所有开放的端口号
netstat -ntl |grep -v Active| grep -v Proto|awk '{print $4}'|awk -F: '{print $NF}'
netstat -ntlup |grep -Ev "Active|Proto" |awk '{print $4}' |awk -F: '{print $NF}'