LINUX中文本处理工具awk用法及举例
1.功能简介
AWK是一种非常强大的文本处理工具,它可以读取文件内容,对文件内容进行分析处理,并输出结果。AWK主要用于处理纯文本文件,常被用于数据处理、日志分析、文本转换等领域。
在Linux系统中,AWK 常用于如下场景:
- 查找、分析与输出:
AWK可以通过查找文本文件中的关键字或者行内容来筛选出所需的信息,或者通过对数据进行分析后输出加以提示或警示。 - 数据格式化:
AWK可以将大量的数据转化为可读性更高的,更易于理解的格式,或者通过自定义格式输出特定的报表。 - 编写脚本:
AWK也可以用作脚本编写语言,辅助Linux系统的自动化管理。 - 数据流处理:
AWK还可以通过接受并处理管道传输过来的数据,实现数据流的处理。
其中AWK相对于其他文本处理工具的优势在于,它能够根据用户自定义的各项规则进行灵活匹配和计算,所以 AWK对于数据的处理也更加具有可定制的性质。
2.语法结构
awk options 'selection_pattern { action }' input-file > output-file
2.1选项参数
options:是一些选项,可以用来改变AWK的行为。
-F:指定输入文件的分隔符,默认为正则表达式 /(空格或制表符)+/;-v var=value:定义AWK变量var,并赋值value。
2.2匹配模式
selection_pattern:是一个模式,用于选择符合条件的行,常用的pattern匹配模式包括:
/regexp/:使用正则表达式进行匹配;$1 ~ /regexp/:在第 1 列内容中使用正则表达式进行匹配;BEGIN:在处理文件之前执行;END:在处理文件之后执行。
2.3动作模式
action:是一个动作,对符合条件的行进行操作,常用的action处理模式包括:
{print}:打印当前行;{print $1}:打印第 1 列数据;{printf "%s %s \n", $1, $2}:按照指定格式打印第 1,2 列数据;{sum+=$1}:计算所有行的第 1 列数据之和。
上面selection_pattern和 action可以省略其中一个,但selection_pattern和{ action }不能同时省略。
2.4输入文件
input-file:是输入文件,就是要处理的文本。
2.5输出文件
output-file:是输出文件,这项一般可以不指定,如果没有指定,则输出到屏幕上。.
3.AWK中的变量及操作符
3.1变量
AWK中的变量有两种:
- 预定义变量:
AWK中有一些预定义变量,如$0代表当前行的全部内容,$1代表当前行的第一个字段内容,NF表示当前行的字段数目等等。 - 用户自定义变量:
AWK中可以通过-v参数传入变量,例如awk -v var=value 'script' file表示将变量 var 赋值为 value,然后在AWK脚本中可以通过$var或var来使用该变量。
| 变量名称 | 代表含义 |
|---|---|
NF |
每一行 ($0) 拥有的栏位(分割域)总数 |
NR |
目前awk所处理的是『第几行』的数据 |
FS |
目前的分隔字节,默认是空白键 |
$number |
表示记录的字段。比如,表示第个字段,2表示第2个字段,如此类推。而$0比较特殊,表示整个当前行。 |
3.2操作符
AWK支持多种操作符,作为条件判断时常用的有:
| 操作符类型 | 符号表示 | 作用 |
|---|---|---|
| 比较操作符 | ==, !=, <, >, <=, >= |
进行数据比较 |
| 逻辑操作符 | &&, ` |
|
| 字符串操作符 | ~ 和 !~ |
进行正则表达式匹配 |
4. AWK中一些常用的内置函数
split(string, array, fieldsep):将字符串string按照分隔符fieldsep分割成多个子串,并存到数组array中。length([string]):返回字符串string的长度,如果没有参数则返回当前行的长度。substr(string, start, length):返回字符串string从start位置开始(从1开始计数)到length位置的子串。index(string, substring):返回字符串string中子串substring第一次出现的位置(从 1 开始计数),如果没有则返回0。tolower([string])和toupper([string]):将字符串string转换为小写或大写,如果没有参数则分别转换当前行中的所有字符为小写或大写。gsub(regexp, replacement, [target])和sub(regexp, replacement, [target]):用replacement替换字符串target中所有或第一个符合正则表达式regexp的子串,并返回替换次数。
5.常见用法及举例
5.1基本文件处理操作
示例1:在/etc/passwd中显示含root的行:
[root@MyGit ~]# awk '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@MyGit ~]#
示例2:在/etc/passwd中显示每一行中第1列和第2列的字段:
[root@MyGit ~]# awk '{print $1,$2}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
……
这里有个问题,本来想输出前2列,结果全输出了,因为默认是空格为分隔符,所以这里需要指定一下,如下示例3。
示例3:上面示例加选项参数-F,在/etc/passwd中显示每一行中第1列和第2列的字段:
[root@MyGit ~]# awk -F: '{print $1,$2}' /etc/passwd
root x
bin x
daemon x
……
5.2 LINUX系统日常管理中用到的awk操作命令
示例1:获取 CPU 占用率前5的进程
[root@kzkvm2020 ~]# ps -ef | awk '{if ($3>0) print $0}' | sort -k3 -n -r | head -n 5
root 21688 20951 0 12:03 pts/5 00:00:00 head -n 5
root 21687 20951 0 12:03 pts/5 00:00:00 sort -k3 -n -r
root 21686 20951 0 12:03 pts/5 00:00:00 awk {if ($3>0) print $0}
root 21685 20951 0 12:03 pts/5 00:00:00 ps -ef
root 20951 20910 0 12:01 pts/5 00:00:00 -bash
[root@kzkvm2020 ~]#
上述命令使用ps 命令获取进程信息,并将其输出到 AWK中处理。AWK会筛选出CPU占用率大于0的进程,然后使用sort 命令按照第三列(CPU 占用率)进行逆序排列,并选取前5行输出。
示例2:获取内存占用率前5的进程
[root@kzkvm2020 ~]# ps -e -o pid,user,pmem,pcpu,comm | awk '{sum[$2]+=$3} END{for (i in sum) print i,sum[i]}' | sort -k2 -n -r | head -n 5
qemu 64.6
USER 0
rtkit 0
rpc 0
root 0
[root@kzkvm2020 ~]#
上述命令使用 ps命令获取进程信息,并使用AWK统计每个用户(第二列)的内存占用率(第三列)之和。最后使用sort命令按照第二列进行逆序排列,并选取前5行输出。
示例3:查找某个目录下最大的3个文件
[root@MyGit /]# du -a /etc | sort -rn | awk '{print $2}' | head -n 3 | xargs ls -lh
使用du命令获取目录下所有文件的信息,并将其输出到sort命令中进行逆序排列。然后使用AWK将排列后的结果第二列(文件路径)输出,并选取前3行。最后使用xargs命令将待查找的文件路径作为参数传递给ls命令,以便查看文件大小和属性。
示例4:获取某个进程的占用端口
[root@MyGit /]# netstat -nlpt | awk -v p="java.*tomcat" '$0~p {sub(/.*:/,"",$4);print $4}'
[root@MyGit /]#
该命令首先运行netstat -nlpt命令来检查所有活动的网络连接,并使用管道符将输出传递给awk命令。
在awk命令中,使用了一个变量 p 匹配Tomcat进程。变量 p 中的值是一个正则表达式,用于匹配包含java和tomcat关键字的进程。
一旦找到匹配的进程,sub(/.*:/,"",$4)将过滤掉端口号前面的无用信息,只留下端口号。
最后,输出被传递给stdout,显示使用Tomcat进程占用的端口号。
示例5:批量修改文件名
ls | awk '{print "mv "$0" "$0".bak"}' | sh
上述命令使用ls命令列出当前目录下的所有文件名,并使用 AWK生成一条逐个修改文件名的命令。最后使用sh命令执行生成的命令。上述命令实际上是将每个文件名后面加上了 .bak后缀。
示例6:监控文件夹中文件变化
[root@MyGit ~]# ls -lh /home/ | awk '{print $5, $6, $7, $9}'
4.0K 3月 31 moonrong
78 4月 25 mysmb01
6 4月 25 samba
17 4月 25 samba_share
[root@MyGit ~]#
使用ls命令列出指定目录下的文件及其属性,并使用AWK仅输出文件大小、修改日期、文件名信息。这个命令可以用于在终端监测指定目录的文件变化。
示例7:计算某个进程的内存使用量
[root@MyGit ~]# ps -p 3225 -o rss | awk 'NR>1{print $1}'
15844
[root@MyGit ~]#
上述命令使用ps命令获取指定进程的内存使用量。使用-p参数指定进程ID号3225,-o 参数仅输出进程的RSS信息。最后使用AWK跳过第一行,仅输出第一列(RSS信息)。
示例8:列出磁盘空间占用情况
[root@MyGit ~]# df -h | awk '{if (NR!=1) print $1, $5}'
devtmpfs 0%
tmpfs 0%
tmpfs 2%
tmpfs 0%
/dev/mapper/centos-root 34%
/dev/vda1 20%
/dev/mapper/centos-home 1%
tmpfs 1%
tmpfs 0%
[root@MyGit ~]#
上述命令使用df命令列出磁盘空间占用情况,并使用AWK跳过第一行,仅输出第一列(磁盘分区)和第五列(空间占用率)。
示例9:获取网卡的IP地址
[root@MyGit ~]# ifconfig | awk '/inet /{ print $2 }'
192.168.250.239
127.0.0.1
192.168.122.1
[root@MyGit ~]#
示例10:计算某个文件的行数
[root@MyGit ~]# cat get-docker.sh | awk 'END {print NR}'
7
[root@MyGit ~]#
使用cat命令读取指定文件,并使用AWK计算文件的总行数。
示例11:统计访问日志中的 IP 地址
cat access.log | awk '{print $1}' | sort | uniq -c | sort -rn
上述命令使用 cat命令读取指定的访问日志文件,并使用 AWK仅输出日志中的第一列(IP地址)。然后使用sort对IP地址进行排序,再使用uniq -c统计每个IP出现的次数,并再次使用sort 对结果进行排序。
示例12:将秒数转换为时间格式
[root@MyGit /]# echo 3661 | awk '{printf "%02d:%02d:%02d\n",int($1/3600),int(($1%3600)/60),$1%60}'
01:01:01
[root@MyGit /]#
将 3661秒转换为时:分:秒的格式,并使用AWK的printf函数进行格式化输出。
示例13:提取日志中的关键字和日期
cat access.log | awk '{print $1, $4, $7}' | grep "keyword"
上述命令使用 cat 命令读取指定的访问日志文件,使用 AWK 提取日志中的第一列(IP地址)、第四列(日期时间)和第七列(请求路径)。然后使用 grep 过滤出包含指定关键字的行。
示例14:使用 AWK 实现加法计算
[root@MyGit /]# echo "2+3" | awk '{print $0"="($1+$3)}'
2+3=2
[root@MyGit /]#
示例15:计算字符串长度
[root@MyGit /]# echo "Hello World" | awk '{print length($0)}'
11
[root@MyGit /]#
浙公网安备 33010602011771号