awk
awk是处理文本文件的一个应用程序,几乎所有 Linux 系统都自带这个程序。
它依次处理文件的每一行,并读取里面的每一个字段。对于日志、CSV 那样的每行格式相同的文本文件,awk可能是最方便的工具。
1.截取文档中的某个段
awk -F ':' '{print $1}' test.txt
- -F 选项的作用是指定分隔符, 不加-F则以空格或tab为分隔符.
- print为打印的动作,用来打印某个字段, $1 第一个字段
- $0 比较特出,表示整行
awk的格式-F后边紧跟单引号,单引号里面为分隔符; print的动作用{}括起来. print还可以打印自定义的内容, 但是自定义的内容要用双引号""括起来
[root@lz-01 awk]# awk -F ':' '{print $1, $2"#"}' test.txt
root x#
bin x#
daemon x#
adm x#
- 上例中print命令里面的逗号,表示输出的时候,两个部分之间使用空格分隔。
2.匹配字符或者字符串
[root@lz-01 awk]# awk -F ':' '$1 ~ /oo/' test.txt
root:x:0:0:root:/root:/bin/bash
- 上例中 ~ 表示匹配意思. 即匹配第一段中含有oo的行
- 支持正则符号,不需要转义
多次匹配
[root@lz-01 awk]# awk -F ':' '/root/ {print $1,$3} /test/ {print $1,$3}' test.txt
root 0
operator 11
- awk匹配完root,再匹配test. 只打印所匹配的段
3.条件操作符
[root@lz-01 awk]# awk -F ':' '$3=="0"' test.txt
root:x:0:0:root:/root:/bin/bash
-
awk 中可以使用逻辑符号进行判断.
-
在和数字进行判断时,若把比较的数字用双引号括起来,awk不认为是数字,而会认为字符, 不加双引号则会认为数字
[root@lz-01 awk]# awk -F ':' '$7!="/sbin/nologin"' test.txt root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt user1:x:1000:1000::/home/user1:/bin/bash user5:x:1005:1006::/home/user5:/bin/bash user3:x:1006:1007::/home/user3:/bin/bash
-
"/sbin/nologin"用双引号引用
[root@lz-01 awk]# awk -F ':' '$7!="/sbin/nologin" && $3>1005' test.txt user3:x:1006:1007::/home/user3:/bin/bash [root@lz-01 awk]# awk -F ':' '$7!="/sbin/nologin" && $3>"1005"' test.txt sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt user3:x:1006:1007::/home/user3:/bin/bash
-
两个段进行逻辑比较还可使用&& 和 || 分别表示并且和或者.
4.内置变量
常用变量有OFS , NF和NR, 含义如下:
-
OFS 和-F类似,也是用来定义分隔符的,但OFS在输出的时候定义
-
NF 表示用分隔符分割后一共有多少段,
-
NR 表示行号
[root@lz-01 awk]# awk -F ':' '{OFS="#"} $3>1000 || $7 ~ /bash/ {print $1, $3, $7}' test.txt root#0#/bin/bash user1#1000#/bin/bash user4#1004#/sbin/nologin user5#1005#/bin/bash user3#1006#/bin/bash [root@lz-01 awk]# awk -F ':' '{OFS="#"} {if ($3>1000) {print $1, $3, $7}}' test.txt user4#1004#/sbin/nologin user5#1005#/bin/bash user3#1006#/bin/bash
-
上例中加入if判断
[root@lz-01 awk]# head -n3 test.txt |awk -F ':' '{print NF}' 7 7 7 [root@lz-01 awk]# head -n3 test.txt |awk -F ':' '{print $NF}' /bin/bash /sbin/nologin /sbin/nologin [root@lz-01 awk]# head -n3 test.txt |awk -F ':' '{print NR}' 1 2 3
-
NF是多少段, $NF是最后一段的值
awk中的数字运算
[root@lz-01 awk]# head -n3 test.txt |awk -F ':' '{OFS=":"} $1="root"'
root:x:0:0:root:/root:/bin/bash
root:x:1:1:bin:/bin:/sbin/nologin
root:x:2:2:daemon:/sbin:/sbin/nologin
-
上例awk可以更改段值
[root@lz-01 awk]# awk -F ':' '{(tot=tot+$3)};END {print tot}' test.txt 6620
-
上例awk计算某个段的总和.
-
END是awk特有语法,表示所有的行都已经执行