文章目录
- 一、AWK
- 1. `awk` 是什么?
- 2. `awk` 的基础语法
- 2.1 选项
- 2.2 模式
- 2.3 动作
- 3. `awk` 的内置变量
- 4. 典型应用场景及示例
- 4.1 打印特定列
- 4.2 条件筛选
- 4.3 使用正则表达式
- 4.4 统计行数
- 4.5 字段操作
- 4.6 使用内置函数
- 4.7 多文件处理
- 4.8 使用自定义变量
- 5. 高级应用:多行处理
- 6. 实战案例:日志分析
- 6.1 提取 IP 地址
- 6.2 提取状态码
- 6.3 统计每个 IP 的访问次数
- 7.begin和end模式
- 7.1`BEGIN` 模式
- 示例 1:初始化变量
- 示例 2:设置输入字段分隔符
- 7.2`END` 模式
- 示例 1:打印总结信息
- 示例 2:统计文件行数
- 7.3 综合示例
- 二、SED
- 1. `sed` 是什么?
- 2. `sed` 的基础语法
- 2.1 选项
- 2.2 命令
- 3. 常用命令及示例
- 3.1 替换(`s`)
- 示例 1:替换文本中的单词
- 示例 2:全局替换(`g` 标志)
- 示例 3:替换第 2 行的内容
- 示例 4:替换匹配正则表达式的行
- 3.2 删除(`d`)
- 示例 1:删除第 5 行
- 示例 2:删除第 5 到第 10 行
- 示例 3:删除所有包含 `error` 的行
- 3.3 打印(`p`)
- 示例 1:打印第 5 行
- 示例 2:打印第 5 到第 10 行
- 示例 3:打印所有包含 `error` 的行
- 3.4 追加(`a`)和插入(`i`)
- 示例 1:在第 5 行后追加文本
- 示例 2:在第 5 行前插入文本
- 3.5 替换整行(`c`)
- 示例 1:将第 5 行替换为新内容
- 4. 高级应用
- 4.1 多命令组合
- 示例:先替换,再删除
- 4.2 直接修改文件(`-i`)
- 示例:直接替换文件中的内容
- 4.3 使用扩展正则表达式(`-r` 或 `-E`)
- 示例:匹配单词边界
- 5. 实战案例:日志处理
- 5.1 删除所有包含 `error` 的行
- 5.2 替换状态码 `200` 为 `OK`
- 5.3 在每行末尾追加注释
- 参考文档
一、AWK
1. awk
是什么?
awk
是一种强大的文本处理工具,主要用于处理结构化的文本数据(如表格、日志文件等)。它能够逐行读取文件内容,根据指定的规则对每一行进行处理,并输出结果。awk
的名字来源于其发明者的姓氏首字母(Aho、Weinberger、Kernighan)。
2. awk
的基础语法
awk
的基本语法如下:
awk [选项] '模式 {动作}' 文件
2.1 选项
-F fs
:指定输入字段分隔符(默认是空格或制表符)。-v var=value
:向awk
脚本传递变量。-f script.awk
:从文件读取awk
脚本。
2.2 模式
模式用于指定哪些行需要执行动作。可以是:
- 空模式(
{}
):匹配所有行。 - 正则表达式(
/pattern/
):匹配符合正则表达式的行。 - 条件表达式(
$1 > 100
):匹配满足条件的行。
2.3 动作
动作是用 {}
包裹的代码块,用于对匹配的行进行处理。可以使用 awk
的内置函数和变量。
3. awk
的内置变量
awk
提供了许多内置变量,用于处理文本数据:
变量 | 作用 |
---|---|
$0 | 当前行的全部内容 |
$1, $2, ... | 当前行的第 1、第 2、… 个字段 |
NF | 当前行的字段数 |
NR | 当前行号(全局) |
FNR | 当前文件的行号 |
FS | 输入字段分隔符(默认是空格或制表符) |
OFS | 输出字段分隔符(默认是空格) |
RS | 输入记录分隔符(默认是换行符) |
ORS | 输出记录分隔符(默认是换行符) |
4. 典型应用场景及示例
4.1 打印特定列
需求:打印 /etc/passwd
文件的第 1 列和第 7 列(字段分隔符是冒号 :
)。
awk -F: '{print $1, $7}' /etc/passwd
4.2 条件筛选
需求:筛选出第 2 列大于 100 的行。
awk '$2 > 100' data.txt
4.3 使用正则表达式
需求:筛选出包含单词 error
的行。
awk '/error/' access.log
4.4 统计行数
需求:统计文件的行数。
awk 'END {print NR}' file.txt
4.5 字段操作
需求:将第 1 列和第 2 列拼接成新的字段,用逗号分隔。
awk -F: '{print $1 "," $2}' /etc/passwd
4.6 使用内置函数
需求:计算每行的字段数。
awk '{print NF}' data.txt
4.7 多文件处理
需求:同时处理多个文件,打印每个文件的行号和内容。
awk '{print FNR, $0}' file1.txt file2.txt
4.8 使用自定义变量
需求:计算所有行的第 3 列的总和。
awk '{sum += $3} END {print sum}' data.txt
5. 高级应用:多行处理
需求:打印每行的前 3 行内容。
awk '{print NR-3, NR-2, NR-1, NR, $0}' data.txt
6. 实战案例:日志分析
假设有一个日志文件 access.log
,格式如下:
192.168.1.1 - - [25/Jul/2024:10:42:35 +0800] "GET /index.html HTTP/1.1" 200 1234
192.168.1.2 - - [25/Jul/2024:10:42:36 +0800] "POST /submit HTTP/1.1" 200 5678
6.1 提取 IP 地址
awk '{print $1}' access.log
6.2 提取状态码
awk '{print $9}' access.log
6.3 统计每个 IP 的访问次数
awk '{ip[$1]++} END {for (i in ip) print i, ip[i]}' access.log
7.begin和end模式
在 awk
中,BEGIN
和 END
是两个特殊的模式。
BEGIN
:在处理任何输入行之前执行一次,适合初始化变量、设置输入字段分隔符等。END
:在处理完所有输入行之后执行一次,适合打印总结信息、执行后续操作等。
7.1BEGIN
模式
BEGIN
模式在处理任何输入行之前执行一次。它通常用于:
- 初始化变量。
- 设置输入字段分隔符(
FS
)。 - 执行一些在处理文件之前需要完成的操作。
示例 1:初始化变量
假设我们要计算文件中所有数字的总和,可以在 BEGIN
中初始化总和变量。
awk 'BEGIN {sum = 0}{sum += $1}END {print "总和是: " sum}' data.txt
示例 2:设置输入字段分隔符
假设文件的字段分隔符是逗号(,
),可以在 BEGIN
中设置 FS
。
awk 'BEGIN {FS=","}{print $1, $2}' data.csv
7.2END
模式
END
模式在处理完所有输入行之后执行一次。它通常用于:
- 打印总结信息。
- 执行一些在处理文件之后需要完成的操作。
示例 1:打印总结信息
假设我们要计算文件中所有数字的总和,并在处理完所有行后打印总和。
awk 'BEGIN {sum = 0}{sum += $1}END {print "总和是: " sum}' data.txt
示例 2:统计文件行数
假设我们要统计文件的行数。
awk 'END {print NR}' file.txt
7.3 综合示例
假设我们有一个日志文件 access.log
,格式如下:
192.168.1.1 - - [25/Jul/2024:10:42:35 +0800] "GET /index.html HTTP/1.1" 200 1234
192.168.1.2 - - [25/Jul/2024:10:42:36 +0800] "POST /submit HTTP/1.1" 200 5678
需求:统计每个状态码的出现次数,并在处理完所有行后打印总结信息。
awk 'BEGIN {FS=" "}{status_code = $9if (status_code in status_count) {status_count[status_code]++} else {status_count[status_code] = 1}}END {for (code in status_count) {print "状态码 " code " 出现了 " status_count[code] " 次"}}' access.log
建议
- 初始化变量:在
BEGIN
中初始化变量,避免在动作块中重复初始化。 - 总结信息:在
END
中打印总结信息,避免在动作块中重复计算。 - 调试:在
BEGIN
和END
中打印调试信息,帮助定位问题。
二、SED
1. sed
是什么?
sed
(Stream Editor)是一种流编辑器,主要用于对文本数据进行处理。它逐行读取输入(可以是文件或标准输入),对每一行执行指定的编辑操作,并输出结果。sed
的操作是基于正则表达式的,非常适合进行文本替换、删除、插入等操作。
2. sed
的基础语法
sed
的基本语法如下:
sed [选项] '命令' 文件
2.1 选项
-i
:直接修改文件内容(慎用,会覆盖原文件)。-e
:允许使用多条命令。-f
:从文件读取命令。-r
或-E
:使用扩展正则表达式(更强大的正则表达式支持)。-n
:静默模式,不自动打印每一行,需要显式使用p
命令打印。
2.2 命令
sed
的命令格式为:
[地址]命令
- 地址:可以是行号(如
5
)、范围(如5,10
)、正则表达式(如/pattern/
)等。 - 命令:常见的命令有
s
(替换)、d
(删除)、p
(打印)、a
(追加)、i
(插入)等。
3. 常用命令及示例
3.1 替换(s
)
sed
最常用的命令是 s
,用于替换文本中的内容。
示例 1:替换文本中的单词
需求:将文件中的所有 foo
替换为 bar
。
sed 's/foo/bar/' file.txt
示例 2:全局替换(g
标志)
需求:将文件中的所有 foo
替换为 bar
(每行替换所有出现的 foo
)。
sed 's/foo/bar/g' file.txt
示例 3:替换第 2 行的内容
需求:只替换第 2 行中的 foo
为 bar
。
sed '2s/foo/bar/' file.txt
示例 4:替换匹配正则表达式的行
需求:只替换包含 error
的行中的 foo
为 bar
。
sed '/error/s/foo/bar/' file.txt
3.2 删除(d
)
删除指定的行。
示例 1:删除第 5 行
sed '5d' file.txt
示例 2:删除第 5 到第 10 行
sed '5,10d' file.txt
示例 3:删除所有包含 error
的行
sed '/error/d' file.txt
3.3 打印(p
)
打印指定的行(通常与 -n
选项一起使用)。
示例 1:打印第 5 行
sed -n '5p' file.txt
示例 2:打印第 5 到第 10 行
sed -n '5,10p' file.txt
示例 3:打印所有包含 error
的行
sed -n '/error/p' file.txt
3.4 追加(a
)和插入(i
)
在指定位置追加或插入文本。
示例 1:在第 5 行后追加文本
sed '5a ===' file.txt
示例 2:在第 5 行前插入文本
sed '5i ===' file.txt
3.5 替换整行(c
)
将指定行替换为新内容。
示例 1:将第 5 行替换为新内容
sed '5c new line' file.txt
4. 高级应用
4.1 多命令组合
可以使用 -e
选项组合多个命令。
示例:先替换,再删除
sed -e 's/foo/bar/' -e '5d' file.txt
4.2 直接修改文件(-i
)
直接修改文件内容(慎用,会覆盖原文件)。
示例:直接替换文件中的内容
sed -i 's/foo/bar/' file.txt
4.3 使用扩展正则表达式(-r
或 -E
)
使用更强大的正则表达式。
示例:匹配单词边界
sed -r 's/\bfoo\b/bar/' file.txt
5. 实战案例:日志处理
假设有一个日志文件 access.log
,格式如下:
192.168.1.1 - - [25/Jul/2024:10:42:35 +0800] "GET /index.html HTTP/1.1" 200 1234
192.168.1.2 - - [25/Jul/2024:10:42:36 +0800] "POST /submit HTTP/1.1" 200 5678
5.1 删除所有包含 error
的行
sed '/error/d' access.log
5.2 替换状态码 200
为 OK
sed 's/200/OK/' access.log
5.3 在每行末尾追加注释
sed 's/$/ # processed/' access.log
参考文档
- 官方文档:GNU Sed Manual
- 在线教程:Sed One-Liners Explained
- 官方文档:GNU Awk User’s Guide
- 在线教程:Learn Awk the Hard Way