文本处理工具:grep,sed,awk
grep,egrep,fgrep:文本过滤工具:parrern
sed:行编辑器
模式空间,保持空间
awk:报表生成器,格式化文件输出
awk:Aho,Weinberger,Kernighan-->New AWK, NAWK
GNU awk ->gawk
AWK位置:
[root@Test~]# whereis awk
awk:/bin/awk /usr/bin/awk /usr/libexec/awk /usr/share/awk/usr/share/man/man1/awk.1.gz
[root@Test~]# ls -l /usr/bin/awk
lrwxrwxrwx.1 root root 14 Jul 19 22:31 /usr/bin/awk -> ../../bin/gawk
gawk - pattern scanning and processing language
gawk 一次只读取一行文本
基本用法:awk [options] 'program' FILE ...
program:PATTERN{ACTIONSTATEMENTS}
语句之间用分号分隔
awk可以有多组命令,但每一组命令必须用单引号引起来
awk'some_cmd' 'some_cmd' 'some_cmd'
工作方式:
先将文本的一行读入缓冲区中,在缓冲区中对文本进行指定格式的切片,通过切片来操作文本数据
awk会遍历文件中的每一行,并逐行进行输出显示
选项:
-F:指明输入时用到的字段分隔符
-vvar=value:用于实现自定义变量
printitems1,item2,....
print$1,$2
要点:
1,逗号分隔符:
2,输出的各item可以是字符串,也可以是数值,当前记录的字段,变量或awk的表达式
3.如果省略item,相关于print$0 ,打印整行字符
打印指定输入的字段:
[root@Test~]# tail -5 fstab | awk '{print $2,$4}'
swapdefaults
[root@Test~]# tail -5 fstab | awk '{print "hello:$1"}' #在引号内直接输出$1
hello:$1
[root@Test~]# tail -5 fstab | awk '{print "hello:"$1}' #在引号外解析$1
hello:/dev/mapper/vg_test-lv_swap
[root@Test~]# tail -5 fstab | awk '{print}' #打印所有的内容,相关于print$0
[root@Test~]# tail -5 fstab | awk '{print $0}'
/dev/mapper/vg_test-lv_swapswap swap defaults 0 0
[root@Test ~]# tail -5 fstab | awk'{print " "}' #显示空白行
变量:
内建变量: 引用变量不需要加$,但通过$1,$2,$n来引用除外
FS:inputfield seperator :输入时使用的字段分隔符,默认使用空格符
OFS:outputfield seperator:输出时使用的字段分隔符,默认使用空格符
RS:inputrecord seperator:输入时使用的行分隔符,输入时的换行符
ORS:outputrecord seperator:输出时使用的行分隔符,输出时的换行符
NF:numberof field:以空格为分隔符,输出计算后的字段值
{printNF}, {print $NF}
NR:numberof record,显示文件中的行数
FNR:filenumber of record 对每一个文件分别计算行数
FILENAME:文件名
ARGC:命令行参数的个数
ARGV:数组,保存的是命令行中所给定的各参数
[root@Test~]# awk -vFS=":" '{print $1}'/etc/passwd #指明输入时使用的分隔符
root
bin
daemon
[root@Test~]# awk -F ":" '{print $1}' /etc/passwd
root
bin
daemon
[root@Test~]# tail -5 /etc/passwd |awk -v FS=":" -v OFS=">>" '{print $1,$2}'
nobody>>x
vcsa>>x
[root@Test~]# sed -n '16p' /etc/passwd
vcsa:x:69:69:virtualconsole memory owner:/dev:/sbin/nologin
[root@Test~]# sed -n '16p' /etc/passwd | awk -v RS=' ' '{print $0}' #将空格做为换行符
vcsa:x:69:69:virtual
console
memory
owner:/dev:/sbin/nologin
[root@Test~]# sed -n '16p' /etc/passwd | awk -v RS=' ' -v ORS='#' '{print $0}' #输出换行符
vcsa:x:69:69:virtual#console#memory#owner:/dev:/sbin/nologin
[root@Test~]# sed -n '6p' /etc/fstab | awk '{print NF}' #查看这行有几个字段数量
9 #代表这行有9个字段,以空格为分隔符
[root@Test~]# sed -n '6p' /etc/fstab | awk '{print $NF}' #查看指定字段数值下的内容
'/dev/disk' #查看最后一个字段的值
对文件进行编号:
[root@Test~]# awk '{print NR}' /etc/fstab
1
2
3
4
5
6
[root@Test~]# awk '{print FNR}' /etc/fstab /etc/issue
1
2
3
4
1
2
3
[root@Test~]# awk '{print FILENAME}' /etc/fstab #显示操作的文件的文件名
/etc/fstab
/etc/fstab
/etc/fstab
[root@Test~]# awk 'BEGIN{print ARGC}' /etc/fstab #显示参数的个数
2
[root@Test~]# awk 'BEGIN{print ARGV[0]}' /etc/fstab #显示参数的值,第一个参数
awk
[root@Test~]# awk 'BEGIN{print ARGV[1]}' /etc/fstab #显示参数的值,第二个参数
/etc/fstab
自定义变量:
(1)-v var=value
变量名区分字符大小写:
(2) 在program中直接定义
[root@Test~]# awk -v test='hello gawk' '{print test}' /etc/fstab
hellogawk
hellogawk
[root@Test~]# awk -v test='hello gawk' 'BEGIN{print test}'
hellogawk
[root@Test~]# awk 'BEGIN{test="hello gawk";print test}'
hellogawk
printf命令:
格式化输出:printf FORMAT, item1,item2,....
(1):FORMAT必须要给出
(2):不会自动换行,需要显示给出换行控制符,\n
(3):FORMAT中需要分别为后面的每个item指定一个格式化符号
格式符:
%c:显示字符的ASCII码:
%d,%i:显示十进制整数
%e,%E:显示科学计数法数据显示
%f:显示为浮点数
%g,%G:以科学计数法或浮点形式显示数值
%s:显示字符串
%u:无符号整数
%%:显示%自已
修饰符:
#[.#]:第一个数字控制显示的宽度(默认右对齐),第二个数字表示小数点后的精度
%3.1f
-:表示左对齐
+:显示数值的符号
[root@Test~]# awk -F ":" '{printf "Username: %s\n",$1}'/etc/passwd #修饰符
Username:root
Username:bin
[root@Test ~]# awk -F":" '{printf "Username: %s UID:%d\n",$1,$3}'/etc/passwd#修饰符
Username:root UID:0
Username:bin UID:1
Username:daemon UID:2
Username:adm UID:3
Username:lp UID:4
[root@Test~]# awk -F ":" '{printf "Username: %-15sUID:%d\n",$1,$3}' /etc/passwd#左对齐
Username:root UID:0
Username:bin UID:1
Username:daemon UID:2
Username:adm UID:3
Username: lp UID:4
操作符:
算术操作符:
x+y,x-y,x*y,x/y,x^y,x%y
-x:负数
+x:将字符串转换为数值
字符串操作符:没有符号的操作符,字符串连接
赋值操作符:
=,+=,-=,*=,/=,%=,^=
++,--
比较操作符:
>,>=,<,<=,!=,==
模式匹配符:
~:是否匹配,左边的字符串是否匹配右边的字符串
!:是否不匹配,左边的字符串是否不能匹配右边的字符串
逻辑操作符:
&&
||
!
函数调用:
function_name(argu1,argu2,...)
条件表达式:
selector?if-true-expression:if-false-expression
通过UID判断是不是系统用户
[root@Test ~]# awk -F :'{$3>=500?usertype="common user":usertype="Systemadmin orSysUser";printf "%-15s:%-s\n",$1,usertype}' /etc/passwd
root :Systemadmin or SysUser
bin :Systemadmin or SysUser
daemon :Systemadmin or SysUser
Pattern:地址定界符:
(1):empty:处理文件的每一行,匹配每一行
(2):/regular expression/:能匹配的行才是需要的行,仅处理能够被此模式匹配的行
(3):relational expression:关系表达式,结果有真有假,结果为真的才会被处理,结果非0值表示真,结果非空字符串为真
(4):line ranges:行范围,指定行的范围,相关于地址定界
/pat1/,/pat2/
注意:不支持直接给出数字的格式
(5)BEGIN/END模式:
BEGIN{}:仅在开始处理文件中的文本之前执行一次,在处理文件内容开始之前要运行的命令
END{}:仅在文本处理完成之后执行一次,在处理文件内容完成之后要运行的命令
[root@Test ~]# awk '/^proc/{print$1}' /etc/fstab
proc
[root@Test~]# awk '/^proc/{print $0}' /etc/fstab
proc /proc proc defaults 0 0
[root@Test~]# awk -F: '$3<80{print $1,$3}' /etc/passwd #关系表达式
root 0
bin 1
daemon2
adm 3
lp 4
[root@Test~]# awk -F: '$NF=="/bin/bash" {print $1,$NF} ' /etc/passwd #查看用户默认shell是bash
root/bin/bash
查看 $NF最后一个数据的值是否是以bash结尾,如果为真就输出匹配的这一行
[root@Test~]# awk -F: '$NF~/bash$/ {print $1,$NF} ' /etc/passwd
root/bin/bash
[root@Test~]# awk -F: '/^root/,/^daemon/{print $1}' /etc/passwd
root
bin
daemon
[root@Test~]# awk -F: '(NR>2&&NR<=10){print $1}' /etc/passwd #输出第2行和第10行的内容
daemon
adm
lp
sync
shutdown
halt
uucp
通过BEGIN打印报表头:
[root@Test~]# awk -F: 'BEGIN{print "username uid \n======================="}{printf "username:%-10sUID:%-10s\n", $1,$3}' /etc/passwd
username uid
=======================
username:root UID:0
username:bin UID:1
username:daemon UID:2
username:adm UID:3
[root@Test~]# awk -F: 'BEGIN{print "username uid \n======================="}''$3<10{printf "username:%-10s UID:%-10s\n", $1,$3}''END{print"============\n End"}' /etc/passwd
username uid
<span style="font-family:'微软雅黑','sans-serif';color:black;fon