awk实例教程

awk简介:

awk是文本分析工具,对数据进行分析并生成报告,原理为awk把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。

awk命令格式:

在操作之前,我们先来看看awk的使用格式:

awk '{pattern + action}' {filenames}

 
awk是命令,在一个花括号内 pattern 表示 AWK 在数据中查找的模式,比如我们用grep来筛选,而 action 是一种行为,意思是在找到匹配内容时所执行的一系列命令(动作)。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。
awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。
通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。 

awk使用方法:

1.命令行方式
awk 参数  '匹配模式+动作'  文件名
其中, '匹配模式+动作'是真正awk命令,比如上面单引号里的
'{pattern + action}' ;而参数是可选的。 比如我们使用-F选项,表示域分隔符,就像excel里用不同的符号对列进行分割,文件名就是我们要处理的数据文件。

在awk中,文件的每一行中,由域分隔符分开的每一项的集合被称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。

2.shell脚本方式
将所有的awk命令写入一个文件,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。
相当于shell脚本首行的:#!/bin/sh
换成:#!/bin/awk

3.将awk命令写入一个文件,使用awk命令调用:
awk -f awk_file file
其中,-f选项加载awk_file中的awk脚本文件,file就是被处理的数据文件。

awk命令实例:

我们对下面这个数据进行处理,首先分析这个文件,而很多列,用空格分隔,第二列是进程号,是我们需要提取的列。

[eyeglasses@slave3 ~]$ ps -aux | grep jupyter
 eyeglas+   8824  0.1  0.1 502056 78552 ?        Sl   Jul16 120:51 /home/eyeglasses/anaconda3/bin/python /home/eyeglasses/anaconda3/bin/jupyter-notebook
 eyeglas+   8902  0.0  0.0 755164 51936 ?        Ssl  Sep05   0:05 /home/eyeglasses/anaconda3/bin/python -m ipykernel_launcher -f /run/user/1002/jupyter/kernel-f1cc3df1-d8e4-4602-a67c-c0aba38364e4.json
 eyeglas+   8954  0.0  0.1 1695548 128904 ?      Ssl  Sep05   0:11 /home/eyeglasses/anaconda3/bin/python -m ipykernel_launcher -f /run/user/1002/jupyter/kernel-725960b0-9033-479a-b8c4-abab6fde5916.json
 eyeglas+   9231  0.0  0.1 1482332 95336 ?       Ssl  Sep05   0:08 /home/eyeglasses/anaconda3/bin/python -m ipykernel_launcher -f /run/user/1002/jupyter/kernel-69e175f3-abe9-4f2c-8997-af5162b81aef.json
 eyeglas+  10852  0.0  0.0 755164 53792 ?        Ssl  Sep05   0:06 /home/eyeglasses/anaconda3/bin/python -m ipykernel_launcher -f /run/user/1002/jupyter/kernel-67383592-3b8f-4ed9-87c1-e7c081b095d0.json
 eyeglas+  10946  0.0  0.0 755164 51996 ?        Ssl  Sep05   0:05 /home/eyeglasses/anaconda3/bin/python -m ipykernel_launcher -f /run/user/1002/jupyter/kernel-7c345c59-a922-4ede-a027-af323b229fb4.json
 eyeglas+  10988  0.0  0.0 755168 51604 ?        Ssl  Sep05   0:05 /home/eyeglasses/anaconda3/bin/python -m ipykernel_launcher -f /run/user/1002/jupyter/kernel-830a0b2a-ffab-4778-9e5e-54c730c7f5cc.json
 eyeglas+  77358  0.0  0.0 112708   960 pts/0    S+   09:40   0:00 grep --color=auto jupyter
---------------------------------------------------
这里我们只使用awk列出第2行
$ ps -aux | grep jupyter |awk '{print $2}' >> pid.txt

8824

8902

8954

9231

10852

10946

10988

77782

使用for语句kill这些进程:

这里输出
-bash: kill: (78339) – No such process 是因为78339是ps显示的进程,所以没有被匹配,而其他进程都被杀掉。

$ for i in cat pid.txt;do kill $i;done
-bash: kill: (78339) – No such process

下面说明使用冒号做分隔的例子:

$ ps -aux | grep jupyter
eyeglas+ 79156 1.7 0.0 470072 64012 pts/0 Sl 10:06 0:01 /home/eyeglasses/anaconda3/bin/python /home/eyeglasses/anaconda3/bin/jupyter-notebook
eyeglas+ 79262 11.9 0.0 755168 52012 ? Ssl 10:08 0:01 /home/eyeglasses/anaconda3/bin/python -m ipykernel_launcher -f /home/eyeglasses/.local/share/jupyter/runtime/kernel-d6713ff4-a6ce-4690-81b8-f67895c325f9.json
eyeglas+ 79297 0.0 0.0 112704 964 pts/0 S+ 10:08 0:00 grep –color=auto jupyter
上面这个输出是我们要处理的数据,我们是:做分隔符来处理。

$ ps -aux | grep jupyter | awk -F ‘:’ ‘{print $1}’
eyeglas+ 79156 1.1 0.0 470072 64012 pts/0 Sl 10
eyeglas+ 79262 1.8 0.0 755168 52012 ? Ssl 10
eyeglas+ 79364 0.0 0.0 112704 960 pts/0 S+ 10

$ ps -aux | grep jupyter | awk -F ‘:’ ‘{print $2}’
06 0
08 0
09 0

$ ps -aux | grep jupyter | awk -F ‘:’ ‘{print $3}’
01 /home/eyeglasses/anaconda3/bin/python /home/eyeglasses/anaconda3/bin/jupyter-notebook
01 /home/eyeglasses/anaconda3/bin/python -m ipykernel_launcher -f /home/eyeglasses/.local/share/jupyter/runtime/kernel-d6713ff4-a6ce-4690-81b8-f67895c325f9.json
00 grep –color=auto jupyter

我们可以看到,数据文件里有两个冒号,被分割成三部分,上面是打印的结果。

如果我们只想打印冒号分隔前两列的结果,使用如下命令:

$ ps -aux | grep jupyter | awk -F ‘:’ ‘{print $1″\t”$2}’
eyeglas+ 79156 0.3 0.0 470072 64012 pts/0 Sl 10 06 0
eyeglas+ 79262 0.2 0.0 755168 52012 ? Ssl 10 08 0
eyeglas+ 79891 0.0 0.0 112704 956 pts/0 S+ 10 17 0

“\t”是制表符分隔。

有些时候,我们需要提取数据文件里的列,并为这些列命名,我们以/etc/passwd文件为例说明:

cat /etc/passwd |awk -F ‘:’ ‘BEGIN {print “name,shell”} {print $1″,”$7}’ | head -n 6

使用BEGIN知名列名,head命令只显示前6行。

过滤结果如下,
name,shell
root,/bin/bash
bin,/sbin/nologin
daemon,/sbin/nologin
adm,/sbin/nologin
lp,/sbin/nologin

使用正则表达式awk命令例子:

$ ll | awk ‘/my/ {print $9}’
mydata.bak
mydata.dat
mydata.dir
my.ini
mypython
mysql-cluster-gpl-7.5.15-linux-glibc2.12-x86_64.tar.gz
mysql-cluster-gpl-7.5.15.tar.gz

列出ll输出结果的第九列,这个列是文件名称,显示包含my的结果。

awk内置变量:


awk有许多内置变量,下面是最常用的变量,注意都是大写。


ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行 -F选项
NF 浏览记录的域的个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
注意:$0变量是指整条记录。$1表示当前行的第一个域,$2表示当前行的第二个域,以此类推。


发表评论

电子邮件地址不会被公开。 必填项已用*标注