awk - 运维三剑客
简介
awk 常用于循环读取文本,获取某列,像这样 awk -F":" '{print $1}''
实际上它还可以对获取的值做处理,并输出结果
经常见到用朋友用 awk 做统计,搞一下它的用法做个记录
完全体可以分为以下5个部分
变量
内置变量
awk 有一些内置的变量,经常出现在各个大佬的脚本中
$0
: 表示整行$1
,$2
..:表示某列NR
:表示行号NF
:列总数$NF
:也就是最后一列的值FS
:输入列分隔符,默认是" ",也可以通过awk -F
指定OFS
:输出列分隔符,默认是" "。(output field sep)RS
:输入行分隔符,默认是"\n"ORS
:输出行分隔符,默认是"\n"。(output row sep)
变量赋值
有了变量之后,就可以进行赋值、计算和拼接
x = 1
:赋值,弱类型,赋值时不用在意类型x = "1"x
: 拼接字符串x++
或x+=1
:计算
变量使用的示例
# 根据列打印
awk -F: '{print $1,$6}' /etc/passwd
# 在 BEGIN 块中设置输入分隔符
awk 'BEGIN {FS=":"} {print $1,$6}' /etc/passwd
awk -F: '{print $1"="$6}' /etc/passwd
# 在 BEGIN 块中设置输入及输出分隔符
awk 'BEGIN {FS=":";OFS="="} {print $1,$6}' /etc/passwd
# 设置变量, 计算某一列的和
# 变量的赋值和引用都不需要加$符号
awk -F: 'BEGIN{sum=0} {sum+=$3} END{print sum}' /etc/passwd
# 支持隐式设置, 与上边等价(主要是怕有些大佬按这个写法写,看到了不懂)
awk '{sum+=$5} END{print sum}' a
格式化输出
变量支持字符串类型,就有了格式化输出的概念
%s
:字符串占位符,自动长度%10s
:设置占用长度为10,右对齐%-10s
:设置占用长度为10,左对齐
格式化输出示例
需要使用 printf 函数
# 替换字符串, 默认自动长度
# 这里就是之前提到的,只有 BEGIN 块,可以不指定输入
[root@master ~]# awk 'BEGIN {printf "%s: %s\n", "foo", "bar"}'
foo: bar
# 设置字符串占用长度, 前边左对齐,后边右对齐
[root@master ~]# awk 'BEGIN {printf "|%10s|: |%-10s|\n", "foo", "bar"}'
| foo|: |bar |
# 如果超过限制长度自动扩充
[root@master ~]# awk 'BEGIN {printf "|%3s|: |%-3s|\n", "foooooo", "barrrrr"}'
|foooooo|: |barrrrr|
逻辑
主要用于逐行处理,图中 pattern 的部分
匹配
匹配可以是通配符,也可以是正则
绝对匹配时可以不加 //, 模糊匹配必须加 //
如果是按列匹配也可以使用"",但是不通用,建议用//
绝对匹配
(适用于字符串和数字):- 针对列匹配:
awk '($m~root) { print $n }' filename
- 整行匹配:
awk '(/root/) { print $n }' filename
- 针对列匹配:
模糊匹配
(适用于字符串和数字):awk '($m~/ro.*t/) { print $n }' filename
比大小
(适用于数字):awk '($m>42) { print $n }' filename
关联符
&&
(与):awk '($m>2&&$m<9) { print $n } filename'
||
(或):awk '($m<2||$m>5) { print $n }' filename
!
(非):- 针对列不匹配
awk '($m!~/yky/) { print $n } filename
- 针对整行不匹配:
awk '(!/root/) { print $n }' filename
- 针对列不匹配
if 判断
awk 通过匹配也可以实现 if 判断的效果
与匹配模式的区别是,if 判断块需要写在 { } 里边,因为每行都要执行判断
等于
(适用于字符串和数字):awk '{ if($m=="x") print $n }' filename
不等于
(适用于字符串和数字):awk '{ if($!="x") print $n }' filename
大于/小于/大于等于/小于等于/等于
(仅适用于数字):awk '{ if($m<5||9<=$m) print $n }' filename
循环
支持 for 循环和 while 循环
支持 break 和continue
我感觉不是很常用,我没用过= =
for 循环
# 在 BEGIN 中使用 for 循环
awk '
BEGIN {
for(i=0;i<10;i++)
print i
}'
# 这个相当于每读一行文本,都会执行一次完整的for循环
awk '
{
for( i = 1; i < 10; i += 2 )
{print}
}' /etc/passwd
# for range 循环(配合数组使用)
# 两个赋值,一个循环输出
awk '
BEGIN {
arr["a"]="aaa"
arr["b"]="bbb"
for(x in arr)
print arr[x]
}'
while 循环
# 两种写法结果等价
awk '
BEGIN {
while (i < 10) {
print i
i++
}
}'
awk '
BEGIN {
i = 1
do {
print i
i++
} while (i < 10)
}'
引用
引用命令
如果 awk 命令太长,还可以预置成一个文件,在通过 awk -E 的方式引用
文件中只需要声明 awk ' ' 中间的内容
[root@node02 ~]# cat a
BEGIN{
print "----------"
}
[root@node02 ~]# awk -E a
----------
引用变量
这里需要先使用 -v 传入变量
[root@node02 ~]# cat a
BEGIN{
print "sum 初始值为: "sum
}
( $2!=3 ) {sum+=$2}
END{
print sum
}
[root@node02 ~]# cat b
a 1
b 2
c 3
d 4
e 5
# 如果不指定sum变量的初始值,默认为0
[root@node02 ~]# awk -E a b
sum 初始值为:
12
# 但是如果指定的话
[root@node02 ~]# awk -v sum=2 -E a b
sum 初始值为: 2
14
数组
定义数组,循环输出
awk '
BEGIN {
assoc["key1"] = "val1"
assoc["key2"] = "val2"
for (key in assoc)
print assoc[key];
}'
函数
函数名 | 示例 | 说明 |
---|---|---|
length(str) | awk 'BEGIN {a=length("aaa"); print a}' |
字符串长度 |
printf("formatStr", ele1, ele2) | awk 'BEGIN {printf("%s: %s\n", "foo", "bar")}' |
格式化字符串 |
toupper(str) | 转大写 | |
tolower(str) | 转小写 | |
index(a, b) | awk '{print index($0,"root")}' /etc/passwd |
字符串a中出现字符串b的索引, 未找到为0 |
欢迎加 1092845214 交流沟通呀~
本文来自博客园,作者:难德糊涂,转载请注明原文链接:https://www.cnblogs.com/yangkaiyue/p/18235896
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律