awk基础
-F指定分隔符来打印
打印文件最后一列
用斜线屏蔽一下,不然会报错
故意输错密码查看日志
¥11 11列
不是bash结尾的行 都打印出来
错误打了中文的逗号,已修改
钱nf : 最后一列的意思
要理解这个命令的每一步,我们可以分解为 ls -l
、管道 |
、awk
处理逻辑 三部分,逐步解析:
1. ls -l /etc
:列出目录的长格式信息
ls -l
是 长格式列出文件,每行输出包含以下字段(以 /etc/passwd
为例):
-rw-r--r--. 1 root root 1024 Aug 4 10:00 /etc/passwd
- 第1字段(
$1
):文件类型+权限(如-
表示普通文件,d
表示目录,l
表示符号链接等)。 - 后续字段:链接数、所有者、组、大小、修改时间、文件名。
2. 管道 |
:传递 ls
输出给 awk
ls -l /etc | awk '{...}'
表示将 ls
的输出 逐行传递 给 awk
处理。
3. awk
脚本的逻辑:统计目录和普通文件数量
awk
脚本分为 逐行处理段 和 END 结束段:
(1) 逐行处理段:{ if($1~/^d/) {x++} else {y++} }
$1
:表示ls -l
输出中 第1个字段(即文件类型+权限字段)。$1~/^d/
:正则匹配,判断$1
是否 以d
开头(^
表示开头,d
是目录的标识)。x++
和y++
:- 如果是目录(
$1
以d
开头),变量x
加1(统计目录数)。 - 否则(如普通文件
-
、符号链接l
等),变量y
加1(脚本里简化为“普通文件”,实际可能包含其他类型,但题目这么处理)。
- 如果是目录(
(2) END 结束段:END {print "普通文件个数:"x,"目录个数:"y}
END
是awk
的 结束块,在处理完所有行后执行。- 打印变量
y
(非目录的文件数,脚本视为普通文件)和x
(目录数)。
最终效果
命令执行后:
x
统计/etc
中 目录的数量(155个)。y
统计/etc
中 非目录文件的数量(脚本视为普通文件,122个)。
(注意:实际中 y
可能包含符号链接、设备文件等,但脚本简化处理为“普通文件”,这是示例的逻辑设定。)
~: 正则匹配
mkdir -p递归创建目录
要在前面加斜杠 不然没有目录
这样才对
我们分解 awk
命令的 执行阶段 和 代码逻辑,逐步解释:
一、整体结构:awk
的两个核心阶段
{IP[$1]++} # ① 主处理块(逐行处理输入)
END { # ② END 块(所有行处理完后执行)
for(i in IP) {
print i, IP[i]
}
}
/access_log # 处理的文件:/access_log
二、阶段1:主处理块 {IP[$1]++}
(逐行处理日志)
$1
:表示当前行的 第1个字段(默认以空格/制表符分隔,这里每行只有IP,所以$1
就是IP地址,如172.40.1.18
)。IP[$1]
:定义一个 关联数组IP
,以IP为键(如172.40.1.16
),值存访问次数。++
:每次遇到相同IP,对应的值 加1(首次遇到时,IP[$1]
默认是0
,加1后变为1
;再次遇到则变为2
,以此类推)。
三、阶段2:END 块 for(i in IP) {print i, IP[i]}
(统计结果输出)
END
:awk
处理完所有行后,仅执行一次 该块。for(i in IP)
:遍历关联数组IP
的所有 键(i 代表不同的IP地址)。print i, IP[i]
:打印 IP地址(i) 和对应的 访问次数(IP[i])。
示例验证(结合日志内容)
日志内容(tail /access_log
输出):
172.40.1.18
172.40.1.17
172.40.1.18
172.40.1.17
172.40.1.16
172.40.1.18
172.40.1.16
出现 1次 → 输出172.40.1.16 1
172.40.1.17
出现 2次 → 输出172.40.1.17 2
172.40.1.18
出现 3次 → 输出172.40.1.18 3
完全匹配命令的输出结果,逻辑自洽。