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_patternaction可以省略其中一个,但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脚本中可以通过 $varvar 来使用该变量。
变量名称 代表含义
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 中的值是一个正则表达式,用于匹配包含javatomcat关键字的进程。

一旦找到匹配的进程,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参数指定进程ID3225-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地址)。然后使用sortIP地址进行排序,再使用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秒转换为时:分:秒的格式,并使用AWKprintf函数进行格式化输出。

示例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 /]# 
posted @ 2023-08-08 11:29  寻梦99  阅读(792)  评论(0)    收藏  举报