GNU awk 的用法
awk 简介
在Linux 使用的 awk 是GNU awk(gawk)。
文本处理三剑客
文本处理三剑客:
- grep, egrep, fgrep:文本过滤器
- sed:Stream EDitor,流编辑器,行
- awk:文本格式化工具,报告生成器
awk 工作原理
awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。
awk的工作原理:在实现文本处理时,一次处理一行数据,把整行文本按照 字段分隔符 (默认的字段分隔符是空格)切割成 N 片,并赋值到 awk 的内嵌变量中($1 $2 $3 …),遍历文本进行处理。原行可使用 $0 进行调用。还可以做模式匹配、循环等,实现文本化的格式化输出
也可以使用 PATTERN 匹配相应的行进行处理。
示例:
# 在awk.txt文件中,默认分隔符是空格符,会把文件按照空格进行切片处理
# 如下:$1 代表 1; $2 代表 2; ... ;$0 代表 原行
[root@LEEMUMU ~]# cat awk.txt
1 2 3 4 5 6 7 8 9
[root@LEEMUMU ~]# awk '{print $2,$9}' ./awk.txt
2 9
[root@LEEMUMU ~]# awk '{print $5}' ./awk.txt
5
[root@LEEMUMU ~]# awk '{print $0}' ./awk.txt
1 2 3 4 5 6 7 8 9
[root@LEEMUMU ~]# awk '{print $1,$2,$3,$4,$5}' ./awk.txt
1 2 3 4 5
awk 在切片时,与 cut 是有本质区别的,cut 命令只能理解单个空白字符或者固定数量的空白字符。如下。
[root@LEEMUMU ~]# tail -5 /etc/fstab
/dev/mapper/centos-root / xfs defaults 0 0
UUID=a66f32bb-5a9b-459d-91d8-93d8a37f5afa /boot xfs defaults 0 0
UUID=3045-5344 /boot/efi vfat umask=0077,shortname=winnt 0 0
/dev/mapper/centos-home /home xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
[root@LEEMUMU ~]# tail -5 /etc/fstab | cut -d" " -f2,4
/
/boot
/home
swap
[root@LEEMUMU ~]# tail -5 /etc/fstab | awk '{print $2,$4}'
/ defaults
/boot defaults
/boot/efi umask=0077,shortname=winnt
/home defaults
swap defaults
awk 用法
awk 的基本用法如下:
# gawk - pattern scanning and processing language
# 基本用法
# gawk [options] 'program' FILE ...
# program: PATTERN{ACTION STATEMENTS}
# 注意:语句之间用分号分隔
# 常用 ACTION:
# print
# printf:不换行打印输出
# 常用选项:
# -F:指明输入时用到的字段分隔符,默认是空格
# -v var=value: 自定义变量
# 注意:每个 -v 用于定义一个变量
1.print
命令用法:
print item1, item2, ...
此命令使用要点,如下:
- 逗号分隔符: 如果省略 “,” 号的话,会合并输出。
- 输出的各item可以是字符串,也可以是数值,也可以是当前记录的字段、变量或awk的表达式。
- 如省略item,相当于print $0。
[root@LEEMUMU ~]# cat awk.txt
1 2 3 4 5 6 7 8 9
[root@LEEMUMU ~]# awk '{print $1,$2}' ./awk.txt
1 2
[root@LEEMUMU ~]# awk '{print $1$2}' ./awk.txt
12
[root@LEEMUMU ~]# awk '{print $1 $2}' ./awk.txt
12
[root@LEEMUMU ~]# awk '{print "$1 is",$1,";","$2 is",$2,"."}' ./awk.txt
$1 is 1 ; $2 is 2 .
[root@LEEMUMU ~]# awk '{print}' ./awk.txt
1 2 3 4 5 6 7 8 9
[root@LEEMUMU ~]# awk '{print "$0 is",$0,"."}' ./awk.txt
$0 is 1 2 3 4 5 6 7 8 9 .
2.变量
在 awk 中引用变量值的时候不需要加 $ 符号,引用字段时需要加 $ 符号,如果引用的变量是内建变量的话,则不需要加 $ 符号。
2.1 内建变量
演示文本内容:
[root@LEEMUMU ~]# cat awk.txt
1 2 3 4 5 6 7 8 9
[root@LEEMUMU ~]# cat awk2.txt
The Line One:1 2 3
The Line Two:1 2 3
内建变量名称:
FS:input field seperator # 字段分隔符,默认为空白字符
OFS:output field seperator # 输出字段分隔符,默认为空白字符
RS:input record seperator # 记录分隔符,默认是一个换行符
ORS:output record seperator # 输出记录分隔符,默认是一个换行符
NF:number of field # 字段数量
{print NF} # 打印字段数量
{print $NF} # 打印第(字段数量)个分片
示例:
[root@LEEMUMU ~]# awk -v FS=':' -v OFS=':::' '{print $1,$2}' ./awk2.txt
The Line One:::1 2 3
The Line Two:::1 2 3
[root@LEEMUMU ~]# awk -v FS=':' -v OFS='||' '{print $1,$2}' ./awk2.txt
The Line One||1 2 3
The Line Two||1 2 3
[root@LEEMUMU ~]# awk -v FS=' ' -v OFS='|' '{print $1,$2,$3,$4,$5}' ./awk2.txt
The|Line|One:1|2|3
The|Line|Two:1|2|3
[root@LEEMUMU ~]# awk -F: -v ORS='\n::::::::::::::::::\n' '{print $1,$2}' ./awk2.txt
The Line One 1 2 3
::::::::::::::::::
The Line Two 1 2 3
::::::::::::::::::
[root@LEEMUMU ~]# awk -F: -v ORS=' LINE_END\n' '{print $1,$2}' ./awk2.txt
The Line One 1 2 3 LINE_END
The Line Two 1 2 3 LINE_END
[root@LEEMUMU ~]# awk -F: '{print $NF}' ./awk2.txt
1 2 3
1 2 3
[root@LEEMUMU ~]# awk -F: '{print NF}' ./awk2.txt
2
2
内建变量名称:
NR:number of record # 行数
FNR # 各文件分别计数:行数
示例:
[root@LEEMUMU ~]# awk '{print FNR}' ./awk2.txt ./awk.txt
1
2
1
[root@LEEMUMU ~]# awk '{print NR}' ./awk2.txt ./awk.txt
1
2
3
[root@LEEMUMU ~]# awk '{print $NR}' ./awk2.txt ./awk.txt # 着重了解
The
Line
3
内建变量名称:
FILENAME # 当前文件名,遍历文件,进行输出
ARGC # 命令行参数的个数
ARGV # 数组,保存的是命令行所给定的各参数
# 引用参数时不需要加 $
# 仅在开始处理文件中的文本之前执行一次
示例:
[root@LEEMUMU ~]# awk '{print FILENAME}' ./awk2.txt ./awk.txt
./awk2.txt
./awk2.txt
./awk.txt
[root@LEEMUMU ~]# awk '{print ARGC}' ./awk2.txt ./awk.txt
3
3
3
[root@LEEMUMU ~]# awk '{print ARGC}' ./awk2.txt
2
2
[root@LEEMUMU ~]# awk '{print ARGV[0]}' ./awk2.txt ./awk.txt
awk
awk
awk
[root@LEEMUMU ~]# awk '{print ARGV[1]}' ./awk2.txt ./awk.txt
./awk2.txt
./awk2.txt
./awk2.txt
[root@LEEMUMU ~]# awk '{print ARGV[2]}' ./awk2.txt ./awk.txt
./awk.txt
./awk.txt
./awk.txt
[root@LEEMUMU ~]# awk 'BEGIN{print ARGV[2]}' ./awk2.txt ./awk.txt
./awk.txt
[root@LEEMUMU ~]# awk 'BEGIN{print ARGV[1]}' ./awk2.txt ./awk.txt
./awk2.txt
[root@LEEMUMU ~]# awk 'BEGIN{print ARGV[0]}' ./awk2.txt ./awk.txt
awk
2.2 自定义变量
自定义变量有如下两种方式:
1、-v var=value
# 变量名区分字符大小写
# 引用变量不需要 $
示例:
[root@LEEMUMU ~]# awk -v hwo='hello world' '{print hwo}' ./awk.txt
hello world
[root@LEEMUMU ~]# awk -v hwo='hello world' '{print hwo}' ./awk2.txt
hello world
hello world
[root@LEEMUMU ~]# awk -v hwo='hello world' 'BEGIN{print hwo}' ./awk2.txt
hello world
2、 在program中直接定义
# 变量名区分字符大小写
# 引用变量不需要 $
示例:
[root@LEEMUMU ~]# awk '{hwo="hello world";print hwo}' ./awk2.txt
hello world
hello world
[root@LEEMUMU ~]# awk 'BEGIN{hwo="hello world";print hwo}' ./awk2.txt
hello world
[root@LEEMUMU ~]# awk '{hwo="hello world";print hwo}' ./awk.txt
hello world
3.printf 命令
格式化输出命令:printf
命令格式:
# printf FORMAT, item1, item2, ...
格式符:
%c # 显示字符的ASCII码
%d, %i # 显示十进制整数
%e, %E # 科学计数法数值显示
%f # 显示为浮点数
%g, %G # 以科学计数法或浮点形式显示数值
%s # 显示字符串
%u # 无符号整数
%% # 显示%自身
修饰符:
#[.#]:第一个数字控制显示的宽度;第二个#表示小数点后的精度;
%3.1f
-: 左对齐
+:显示数值的符号
注意事项:
- FORMAT必须给出
- 不会自动换行,需要显式给出换行控制符(\n)
- FORMAT中需要分别为后面的每个item指定一个格式化符号
示例:
[root@LEEMUMU ~]# awk -F: '{printf "%+20s|%+20s\n",$1,$2}' ./awk2.txt
The Line One| 1 2 3
The Line Two| 1 2 3
[root@LEEMUMU ~]# awk -F: '{printf "%+20s|%-20s\n",$1,$2}' ./awk2.txt
The Line One|1 2 3
The Line Two|1 2 3
[root@LEEMUMU ~]# awk '{printf "%+20s|%-20s\n",$1,$2}' ./awk.txt
1|2
[root@LEEMUMU ~]# awk '{printf "%-20s|%+20s\n",$1,$2}' ./awk.txt
1 | 2
[root@LEEMUMU ~]# awk '{printf "%-20s|||||%+20s\n",$1,$2}' ./awk.txt
1 ||||| 2
4.操作符
4.1 算术操作符
# x+y
# x-y
# x*y
# x/y
# x^y
# x%y
# -x
# +x # 转换为数值
[root@LEEMUMU ~]# awk '{print $2,"X",$6,"=",$2*$6}' ./awk.txt
2 X 6 = 12
[root@LEEMUMU ~]# awk '{print $2"X" $6 "=" $2*$6}' ./awk.txt
2X6=12
4.2 字符串操作符
没有符号的操作符,字符串连接使用。
4.3 赋值操作符
=
+=, -=, *=, /=, %=, ^= # 增强型赋值
++, --
4.4 比较操作符
>, >=, <, <=, !=, ==
4.5 模式匹配符
~ # 是否匹配
!~ # 是否不匹配
4.6 逻辑操作符
&& # 与运算
|| # 或运算
! # 非运算
4.7 函数调用
# function_name(argu1, argu2, ...)
4.8 条件表达式
# selector?if-true-expression:if-false-expression
示例:UID号大于等于1000的是普通用户,小于1000的是系统用户。
[root@LEEMUMU ~]# awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd
root:Sysadmin or SysUser
bin:Sysadmin or SysUser
......
test3:Common User
5.PATTERN
(1) empty:空模式,匹配每一行
# 默认都是空模式,匹配到每一行
(2) /regular expression/:仅处理能够被此处的模式匹配到的行
条件取反: 加 ! 号
例如:
# awk '/UUID/{print $1}'
# awk '!/UUID/{print $1}'
(3) relational expression: 关系表达式
# 结果有“真”有“假”;结果为“真”才会被处理
# 真:结果为非0值,非空字符串
例如:
# awk -F: '$3>=500{print $1,$3}' /etc/passwd
# awk -F: '$NF=="/bin/bash"{print $1,$7}' /etc/passwd
# awk -F: '$NF~/bash$/{print $1,$7}' /etc/passwd
(4) line ranges:行范围,
# startline,endline:/pat1/,/pat2/
# 注意: 不支持直接给出数字的格式
例如:
# awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd
(5) BEGIN/END模式
# BEGIN{}: 仅在开始处理文件中的文本之前执行一次
# END{}:仅在文本处理完成之后执行一次
[root@LEEMUMU ~]# cat awk3.txt
The Line One A
The Line Two B
The Line Three C
The Line Four D
[root@LEEMUMU ~]# awk '{print $3,$4}' ./awk3.txt
One A
Two B
Three C
Four D
[root@LEEMUMU ~]# awk '/On/{print $3,$4}' ./awk3.txt
One A
[root@LEEMUMU ~]# awk '$3=="Two"{print $3,$4}' ./awk3.txt
Two B
[root@LEEMUMU ~]# awk '$3!="Two"{print $3,$4}' ./awk3.txt
One A
Three C
Four D
[root@LEEMUMU ~]# awk '(NR>=2&&NR<4){print $3,$4}' ./awk3.txt
Two B
Three C
[root@LEEMUMU ~]# awk 'BEGIN{print "=========",$3,$4}' ./awk3.txt
=========
[root@LEEMUMU ~]# awk 'END{print "=========",$3,$4}' ./awk3.txt
========= Four D
6.常用的action
(1) Expressions
(2) Control statements # if, while等
(3) Compound statements # 组合语句
(4) input statements
(5) output statements
7.控制语句
可结合编程语句对以下脚本进行理解。
# if(condition) {statments}
# if(condition) {statments} else {statements}
# while(conditon) {statments}
# do {statements} while(condition)
# for(expr1;expr2;expr3) {statements}
# break
# continue
# delete array[index]
# delete array
# exit
# { statements }
7.1 if-else
适用场景:对awk取得的整行或某个字段做条件判断。
语法格式:
# if(condition) statement [else statement]
示例:
1、UID号大于等于1000的是普通用户,小于1000的是root或系统用户。
[root@LEEMUMU ~]# awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd
root or Sysuser: root
... ...
root or Sysuser: apache
... ...
Common user: test3
2、输出shell类型是/bin/bash的用户。
[root@LEEMUMU ~]# awk -F: '{if($NF=="/bin/bash") print $1":"$7}' /etc/passwd
root:/bin/bash
test1:/bin/bash
test2:/bin/bash
test3:/bin/bash
3、以空白为分隔符,字段数数量大于9个的进行打印输出。
[root@LEEMUMU ~]# awk '{if(NF>9) print $0}' /etc/fstab
# Created by anaconda on Mon Jun 24 00:50:10 2019
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
4、硬盘使用率超过20%进行输出。
[root@LEEMUMU ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 50G 1.4G 49G 3% /
devtmpfs 3.8G 0 3.8G 0% /dev
tmpfs 3.8G 0 3.8G 0% /dev/shm
tmpfs 3.8G 9.0M 3.8G 1% /run
tmpfs 3.8G 0 3.8G 0% /sys/fs/cgroup
/dev/sda4 494M 162M 333M 33% /boot
/dev/sda1 511M 16M 496M 4% /boot/efi
/dev/mapper/centos-home 583G 33M 583G 1% /home
tmpfs 774M 0 774M 0% /run/user/0
[root@LEEMUMU ~]# df -h | awk -F[%] '/^\/dev/{print $1}' | awk '{if($NF>=20) print $1}'
/dev/sda4
7.2 while 循环
适用场景:对一行内的多个字段逐一类似处理时使用;或对数组中的各元素逐一处理时使用。
语法格式:
# while(condition) statement
当条件为“真”时,进入循环;当条件“假”时,退出循环。注意:在条件为假时,循环体一次也不会执行。
示例:
1、文件/etc/grub2-efi.cfg中,统计以linux开头的行的各个单词的字符数量。
# 按行处理,对每行进行处理时,都会重置 参数i
# 当有多个命令时,一定要加{},多个命令之间使用 “;” 隔开
[root@LEEMUMU ~]# awk '/^[[:space:]]*linux/{i=1;while(i<=NF) {print $i,"has",length($i),"characters."; i++}}' /etc/grub2-efi.cfg
linuxefi has 8 characters.
... ...
rhgb has 4 characters.
quiet has 5 characters.
2、文件/etc/grub2-efi.cfg中,统计以linux开头的行的各个单词的字符数量,只显示字符数量大于25个的“”单词“”。
[root@LEEMUMU ~]# awk '/^[[:space:]]*linux/{i=1;while(i<=NF) {if(length($i)>=25) {print $i,"has",length($i),"characters"}; i++}}' /etc/grub2-efi.cfg
/vmlinuz-3.10.0-957.21.3.el7.x86_64 has 35 characters
root=/dev/mapper/centos-root has 28 characters
/vmlinuz-3.10.0-327.el7.x86_64 has 30 characters
root=/dev/mapper/centos-root has 28 characters
/vmlinuz-0-rescue-6de81c231a084f0d9e5b364079dfd456 has 50 characters
root=/dev/mapper/centos-root has 28 characters
7.3 do-while 循环
适用场景:对一行内的多个字段逐一类似处理时使用;或对数组中的各元素逐一处理时使用。
语法格式:
# do statement while(condition)
注意:至少执行一次循环体,不管条件为真为假,都会执行一次循环体。
7.4 for 循环
语法格式:
# for(expr1;expr2;expr3) statement
# for(variable assignment;condition;iteration process) {for-body}
特殊用法:能够遍历数组中的元素。
语法格式
# for(var in array) {for-body}
# var 变量
# in 关键字
# array 数组
# 会遍历数组的每个下标
7.5 switch 语句
语法格式:
# switch(expression) {case VALUE1 or /REGEXP/: statement; case VALUE2 or /REGEXP2/: statement; ...; default: statement}
# case 关键字
# default 都不符合 case 条件时,执行 default 的 statament
7.6 break 和 continue
# break [n] # 跳出当前循环
# continue # 跳入下一轮循环
7.7 next
# next # 提前结束对本行的处理而直接进入下一行
示例:只输出用户ID是偶数的用户名和ID号。
[root@LEEMUMU ~]# awk -F: '{if($3%2!=0) next; print "even_UID_user:",$1,$3}' /etc/passwd
even_UID_user: root 0
even_UID_user: daemon 2
... ...
even_UID_user: test1 1000
even_UID_user: test3 1002
[root@LEEMUMU ~]#
8.array数组
关联数组语法格式:
# array[index-expression]
# index-expression:
# 可使用任意字符串;字符串要使用双引号
# 例如: weekdays[mon]="Monday"
# 如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”
# 若要判断数组中是否存在某元素,要使用 "index in array" 格式进行
# 若要遍历数组中的每个元素,要使用for循环;
# for(var in array) {for-body}
# 注意:var 会遍历 array 的每个索引
# 例如:for i in array ,变量 i 会遍历数组array的整个索引
## 可以使用 $# 引用我们需要作为索引的字段,并进行对数组变量值进行增强型赋值,这样就可以统计每个文档中字段的个数
如下:
[root@LeeMumu ~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays) {print weekdays[i]}}'
Tuesday
Monday
[root@LeeMumu ~]# awk 'BEGIN{lovers[0]="pangpang";lovers[1]="tangtang";lovers[2]="Neo";for(i in lovers) {print lovers[i]}}'
pangpang
tangtang
Neo
[root@LeeMumu ~]# awk 'BEGIN{lovers[0]="pangpang";lovers[1]="tangtang";lovers[2]="Neo";for(i in lovers) {print i,lovers[i]}}'
0 pangpang
1 tangtang
2 Neo
示例:可以使用 $# 引用我们需要作为索引的字段,并进行对数组变量值进行增强型赋值,这样就可以统计每个文档中字段的个数,例如以下例子,可以统计不同状态的个数。
[root@LEEMUMU ~]# cat awk7.txt
NAME STATUS
aaa online
bbb offline
ccc online
ddd unknown
eee offline
fff online
[root@LEEMUMU ~]# awk '/^[[:lower:]]/{status[$NF]++}END{for(i in status) {print i,status[i]}}' awk7.txt
offline 2
unknown 1
online 3
[root@LEEMUMU ~]# awk '{if($NF=="online") print $1}' awk7.txt
aaa
ccc
fff
[root@LEEMUMU ~]# awk 'BEGIN{print "online_name""\n""==========="}{if($NF=="online") printf "%2s %4-s\n"," ",$1}' awk7.txt
online_name
===========
aaa
ccc
fff
示例:
1、查看网络连接中的监听和建立的TCP数量。
[root@LeeMumu ~]# netstat -tan
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 52 192.168.1.9:22 192.168.1.7:50202 ESTABLISHED
tcp6 0 0 :::22 :::* LISTEN
tcp6 0 0 ::1:25 :::* LISTEN
[root@LeeMumu ~]# netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state) { print i,state[i]}}'
LISTEN 2
ESTABLISHED 1
2、查看httpd的IP地址的连接数量。
[root@LeeMumu ~]# awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log
3、统计/etc/fstab文件中每个文件系统类型出现的次数。
[root@LeeMumu ~]# awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab
xfs 1
4、统计指定文件中每个单词出现的次数。
[root@LeeMumu ~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab
man 1
and/or 1
maintained 1
xfs 3
... ...
under 1
9.函数
9.1 内置函数
- 数值处理:
# rand() # 返回0和1之间一个随机数;
- 字符串处理
length([s]) # 返回指定字符串的长度
sub(r,s,[t]) # 以r表示的模式来查找t所表示的字符中的匹配的内容,并将其第一次出现替换为s所表示的内容
gsub(r,s,[t]) # 以r表示的模式来查找t所表示的字符中的匹配的内容,并将其所有出现均替换为s所表示的内容
split(s,a[,r]) # 以r为分隔符切割字符s,并将切割后的结果保存至a所表示的数组中
示例:
1、split(s,a[,r]) 示例, # 以 r 分隔,前面赋值到下标为 1 的数组变量中,从左到右一次是 1 、2、3、… …
[root@LEEMUMU ~]# cat awk5.txt
IP_ADDRESS1:PORT1
[root@LEEMUMU ~]# awk '{split($1,IP,":")}END{for (i in IP) {print i,IP[i]}}' ./awk5.txt
1 IP_ADDRESS1
2 PORT1
2、网络状态连接中,各个IP地址的连接数量。
[root@LeeMumu ~]# netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for (i in count) {print i,count[i]}}'
192.168.1.7 1
0.0.0.0 2
[root@LeeMumu ~]# netstat -tan
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 52 192.168.1.9:22 192.168.1.7:50202 ESTABLISHED
tcp6 0 0 :::22 :::* LISTEN
tcp6 0 0 ::1:25 :::* LISTEN
[root@LeeMumu ~]#
9.2 自定义函数
可结合bash脚本编程中的函数来加以理解和应用。