真锋
永远保持一颗学习和专注的心
嵌入式视觉
awk、grep、sed命令学习

从很多学习资料都了解到,awk、grep、sed是必须掌握的linux命令之一。

awk、grep、sed是linux操作文本的三大利器,也是必须掌握的linux命令之一。三者的功能都是处理文本,但侧重点各不相同,其中属awk功能最强大,但也最复杂。grep更适合单纯的查找或匹配文本,sed更适合编辑匹配到的文本,awk更适合格式化文本,对文本进行较复杂格式处理

awk

awk 是一个非常好的数据处理工具,相比于 sed 常常作用于一整行的处理, awk 则比较倾向于一行当中分成数个 字段 来处理。因此,awk 适合于小型的数据处理,其命令使用模式如下:

awk '条件类型'{动作1} 条件类型2{动作2} ...' filename

awk 后面接两个单引号并加上大括号 {} 来设定想要对数据进行的处理动作。 awk 可以处理后续接的文件,也可以读取来自前个指令的 standard output 。 awk 主要是处理『每一行的字段内的数据』,而默认的『字段的分隔符为 “空格键” 或 “[tab]键” 』 !(这句话可能比较难理解),直接看下面例子:
使用 last命令可以将 Linux`系统最近的登入者数据打印出来(只取前5行),使用命令: last -n 5

[honggao.zhang@yz-gpu022 float_train]$ last -n 5
zhixuan. pts/154 192.64.38.114 Thu Aug 15 15:20 still logged in 
pengxian pts/153 192.164.37.159 Thu Aug 15 15:19 still logged in 
pengxian pts/152 192.164.37.159 Thu Aug 15 15:13 still logged in 
xinkuan. pts/150 192.191.38.17 Thu Aug 15 15:10 still logged in 
xinkuan. pts/128 192.131.38.17 Thu Aug 15 15:09 still logged in

但是我们想要取出登入者的 IP,且账号与 IP 之间以 [tab] 隔开,使用命令:

last -n 5| awk '{print $1 "\t" $3}

zhixuan. 192.64.38.114 
zhixuan. 153 192.164.37.159 
pengxian 152 192.164.37.159 
pengxian 192.191.38.17 
xinkuan. 192.131.38.17

在这里 last打印的每一行数据都是我要处理的,因此,就不需要“条件类型”的限制,在 awk 括号内,每一行的每个字段都是有变量名称的,第一个字段是 ,第二个字段是1,第二个字段是2,依次类推。总结可得,整个awk 的处理流程如下:

  1. 读入第一行,并将第一行的资料填入 0,1, $2…. 等变数当中;
  2. 依据 “条件类型” 的限制,判断是否需要进行后面的 “动作”;
  3. 做完所有的动作与条件类型;
  4. 若还有后续的『行』的数据,则重复上面 1~3 的步骤,直到所有的数据都读完为止。

awk 是『以行为一次处理的单位』, 而『以字段为最小的处理单位』

awk内建变量

变量名称代表意义
NF每一行 ($0) 拥有的字段总数
NR目前 awk 所处理的是『第几行』数据
FS目前的分隔字符,默认是空格键

如果想要:

  • 列出每一行的账号(就是 $1);
  • 列出目前处理的行数(就是 awk 内的 NR 变量)
  • 并且说明,该行有多少字段(就是 awk 内的 NF 变量)

使用命令:

last -n 5|awk '{print $1 "\t lines: " NR "\t columns: " NF}'

zhixuan. lines: 1 columns: 10 
zhixuan. lines: 2 columns: 10 
pengxian lines: 3 columns: 10 
pengxian lines: 4 columns: 10 
xinkuan. lines: 5 columns: 10

awk 的逻辑运算字符

awk 命令有用到条件类型,自然会涉及到逻辑运算符,如下表:

运算单元代表意义
>大于
<小于
>=大于或等于
<=小于或等于
==等于
!=不等于

举例来说,在 /etc/passwd 当中是以冒号 “:” 来作为字段的分隔, 该文件中第一字段为账号,第三字段则是 UID。那假设要查阅,第三栏小于 10 以下的数据,并且仅列出账号与第三栏,可以使用命令:

cat /etc/passwd | awk '{FS=":"} $3<10 {print $1 "\t" $3}'

root:x:0:0:root:/root:/bin/bash 
bin 1 
daemon 2 
adm 3 
…(以下省略)…

{}花括号里面是你想要做的动作的命令,比如这里要打印账号与第三栏所以有{print $1 "\t" $3}
这里,第一行没有正确的显示出来,这是因为我们读入第一行的时候,那些变数 1,2… 默认还是以空格键为分隔的,所以虽然我们定义了 FS=”:” 了, 但是却仅能在第二行后才开始生效。那么怎么办呢?我们可以预先设定 awk 的变量啊! 利用 BEGIN 这个关键词!使用命令:

cat /etc/passwd | awk 'BEGIN {FS=":"} $3<10 {print $1 "\t" $3}'

root 0 
bin 1 
daemon 2 
…(以下省略)…

awk总结

  • awk 的指令间隔:所有 awk 的动作,亦即在 {} 内的动作,如果有需要多个指令辅助时,可利用分号『;』间隔, 或者直接以 [Enter] 按键来隔开每个指令,例如上面的范例中,鸟哥共按了三次 [enter] 喔!
  • 逻辑运算当中,如果是『等于』的情况,则务必使用两个等号『==』
  • 格式化输出时,在 printf 的格式设定当中,务必加上 \n ,才能进行分行!
  • 与 bash shell 的变量不同,在 awk 当中,变量可以直接使用,不需加上 $ 符号。

参考资料

《鸟哥的Linux私房菜-基础篇》

赞赏

发表评论

textsms
account_circle
email

嵌入式视觉

awk、grep、sed命令学习
从很多学习资料都了解到,awk、grep、sed是必须掌握的linux命令之一。 awk、grep、sed是linux操作文本的三大利器,也是必须掌握的linux命令之一。三者的功能都是处理文本,但侧重点各…
扫描二维码继续阅读
2019-08-15
标签
2019年十一月
« 9月    
 123
45678910
11121314151617
18192021222324
252627282930