の
首页项目归档照片墙音乐说说杂谈🌳 灵境📝 草稿箱友链关于⚙️ 设置
封面

AWK使用笔记总结

原文件✏️修改此篇
写作时间:2026-09-23T16:59:58

AWK使用笔记总结

1. AWK 简介

  • AWK 是一种报告生成器和文本格式化工具,名字取自三位创始人(Alfred Aho, Peter Weinberger, Brian Kernighan)姓氏首字母。
  • Linux 中使用的通常是 gawk(GNU awk)。
  • 它本质上是一门编程语言,支持变量、数组、条件判断、循环等,可视为脚本解释器。
  • 与 grep、sed 并称“Linux三剑客”:
    • grep:擅长单纯的查找或匹配。
    • sed:擅长编辑匹配到的文本。
    • awk:擅长格式化文本,进行较复杂的处理。

2. 基本语法

awk [options] 'pattern { action }' file1 file2 ...
  • options:常用选项如 -F(指定输入分隔符)、-v(设置变量)。
  • pattern:匹配条件(可省略,省略即匹配所有行)。
  • action:对匹配行执行的动作(如 print、printf),必须用 {} 包围。

3. 动作(Action)

最常用的动作是 print 和 printf。

print

  • 输出指定字段或整行。
  • 内置变量:
    • $0:当前整行内容。
    • $1, $2, ...:第1、第2…个字段。
    • $NF:当前行的最后一个字段(NF 表示字段总数)。
    • $(NF-1):倒数第二个字段。
  • 示例:
awk '{print $1, $3}' file        # 打印第1和第3字段
awk '{print $0}' file            # 原样输出整行
awk '{print "用户:", $1, "家目录:", $6}' /etc/passwd

printf

  • 格式化输出,类似C语言,不会自动换行,需手动添加 \n。
  • 常用格式符:%s(字符串)、%d(整数)、%f(浮点数)、%-Ns(左对齐占N列)。
  • 示例:
awk 'BEGIN{printf "%-10s %-15s\n", "用户", "家目录"} {printf "%-10s %-15s\n", $1, $6}' /etc/passwd

4. 模式(Pattern)

模式用于筛选行,满足条件的行才会执行动作。

4.1 空模式

  • 不写任何条件,匹配所有行。

4.2 BEGIN / END 模式

  • BEGIN:在处理任何输入行之前执行,常用于输出表头。
  • END:在所有输入行处理完后执行,常用于输出汇总信息。
  • 示例:
awk 'BEGIN{print "Start"} {print $0} END{print "End"}' file

4.3 关系运算模式

  • 使用比较运算符:<, <=, ==, !=, >=, >。
  • 示例:打印行号为偶数的行
awk 'NR % 2 == 0 {print $0}' /etc/passwd

4.4 正则模式

  • 使用 /正则表达式/ 匹配行。
  • 示例:匹配包含“root”的行
awk '/root/ {print $0}' /etc/passwd
  • 支持 ~(匹配)和 !~(不匹配):
awk '$1 ~ /^[a-z]/' file   # 第1字段以字母开头的行

4.5 行范围模式

  • 格式:/正则1/,/正则2/,表示从匹配正则1的行开始,到匹配正则2的行结束的所有行。
  • 示例:打印从包含“start”到包含“end”之间的行
awk '/start/,/end/ {print}' file

5. 分隔符

5.1 输入分隔符(FS)

  • 默认以空白字符(空格或Tab)为分隔符。
  • 指定方式:
    • -F 选项:awk -F: '{print $1}' /etc/passwd
    • 内置变量 FS:awk -v FS=':' '{print $1}' /etc/passwd

5.2 输出分隔符(OFS)

  • 默认输出字段间以空格分隔。
  • 通过 -v OFS=... 修改。
  • 示例:以逗号分隔输出
awk -v OFS=',' '{print $1, $2}' file

5.3 记录分隔符(RS / ORS)

  • RS(输入记录分隔符):默认换行符,可修改为其他字符,awk按此分割“行”。
  • ORS(输出记录分隔符):默认换行符,输出时用指定符号代替换行。
  • 示例:以 $ 作为行分隔符
awk -v RS='$' '{print}' file

6. 常用内置变量

变量 含义
NF 当前行的字段总数
NR 当前行号(所有文件累计)
FNR 当前行号(每个文件单独计数)
FILENAME 当前处理的文件名
FS 输入字段分隔符
OFS 输出字段分隔符
RS 输入记录分隔符
ORS 输出记录分隔符

示例:

awk '{print NR, FNR, $0}' file1 file2   # 显示累计行号和文件内行号

7. 格式化输出(printf 占位符)

占位符 说明
%s 字符串
%d / %i 十进制整数
%f 浮点数
%c ASCII字符
%x / %X 十六进制(小写/大写)
%% 输出 % 本身
  • 修饰符:- 左对齐,数字 指定宽度,如 %-20s。

8. 分支与循环

  • 语法与C语言类似,但需写在 {} 动作中。
  • if-else:
awk '{ if ($3 > 1000) print $1, "高级用户"; else print $1, "普通用户" }' file
  • for 循环:
awk '{ for (i=1; i<=NF; i++) print $i }' file
  • while / do-while 同理,支持 break / continue。

9. 数组

  • AWK 支持关联数组(索引可以是字符串)。
  • 遍历数组:for (key in array) { ... }
  • 示例:统计单词出现次数
awk '{ for (i=1; i<=NF; i++) count[$i]++ } END { for (w in count) print w, count[w] }' file

10. 常用函数

10.1 算术函数

  • rand():返回 0~1 随机数。
  • srand():设置随机种子。
  • int(x):取整。

10.2 字符串函数

  • length([str]):返回字符串长度(若不指定则返回当前行长度)。
  • gsub(r, s [, t]):全局替换,在 t 中将所有匹配 r 的替换为 s。
  • split(str, arr [, sep]):将字符串按分隔符分割存入数组。
  • 示例:
awk '{ gsub(/old/, "new"); print }' file
awk '{ len = length($1); print len }' file

10.3 排序函数

  • asort(arr [, dest]):对数组值排序(会丢弃关联数组的键,变为数字索引)。
  • 若需保留键值并排序,可借助外部命令 sort:
awk '{ for (i in arr) print i, arr[i] }' file | sort -k2 -nr

11. 实际案例

案例1:统计各用户 shell 类型数量

awk -F: '{ shells[$NF]++ } END { for (s in shells) print s, shells[s] }' /etc/passwd

案例2:打印磁盘已用百分比(df 命令输出)

df -h | awk 'NR>1 {print $1, $5}'   # 第5列是使用率

案例3:处理日志,统计访问IP次数

awk '{ ip[$1]++ } END { for (i in ip) print i, ip[i] }' access.log

12. 注意事项(避坑指南)

  1. 引号问题:awk 程序必须用英文单引号包围,内部变量(如 $1)不要加引号,但普通字符串需加双引号。
  2. 多行写法:单引号内可以换行,Bash会显示 > 提示续行,最后闭合引号即可。
  3. 反斜杠换行:不要在单引号内使用 \ 换行,Bash 不会解释为续行,会导致语法错误。
  4. 正则中的斜杠:若正则包含 /,需转义(\/)。
  5. {n,m} 次数匹配:可能需要加上 --posix 或 --re-interval 选项。
  6. printf 不换行:记得加 \n。
  7. asort 会丢弃关联键:若需保留键,使用外部 sort 或自己实现排序。

SED 使用总结笔记

1. SED 简介

  • 全称:Stream Editor(流编辑器)。
  • 工作方式:sed 逐行处理文本,将当前处理的行读入临时缓冲区(称为模式空间,Pattern Space),然后对缓冲区中的内容进行编辑处理,处理完成后将内容输出到屏幕。
  • 重要特性:默认不修改源文件,除非使用 -i 选项。所有操作都在内存中完成。

2. 基本语法

sed [选项] '脚本命令' 文件名
  • 常用选项:
    • -n:静默模式。取消默认的输出(即不自动打印模式空间内容),常与 p(打印)命令配合使用,只输出我们需要的行。
    • -i:直接修改源文件(非常危险,建议使用前先备份或加后缀,如 -i.bak)。
    • -e:允许在同一行中执行多个脚本命令(逻辑分号 ; 也可实现)。
    • -f:从脚本文件中读取 sed 命令。

3. 核心命令详解

3.1 替换命令 s(最常用)

语法:[address]s/pattern/replacement/flags

  • address:指定操作的行范围(详见第4节)。
  • pattern:要匹配的旧内容(支持正则表达式)。
  • replacement:替换后的新内容。
  • flags(标记):
标记 作用
g 全局替换。替换行内所有匹配到的内容(不加则只替换每行第一个)。
数字(如1,2) 仅替换行内第N次匹配的内容。
p 打印匹配到的行(通常与 -n 结合使用)。
w file 将替换后的结果写入指定文件。
& 代表匹配到的整个内容本身(用于引用匹配串)。
\n 反向引用。匹配 \(\) 中分组的第n个内容。
\ 转义特殊字符(如 /、&)。

实战示例:

# 基本替换(替换每行第一个 "lun")
sed 's/lun/LUN/' awk.txt

# 全局替换(替换所有 "lun")
sed 's/lun/LUN/g' awk.txt

# 只匹配含有"root" 的行,将这行中得bash替换为zsh
sed '/root/s/bash/zsh/' /etc/passwd

# 替换第2次出现的 "lun"
sed 's/lun/LUN/2' awk.txt

# 仅显示被修改的行(-n + p)
sed -n 's/lun/LUN/p' awk.txt

# 将替换结果写入新文件
sed -n 's/lun/LUN/w new.txt' awk.txt

# 使用 & 引用匹配内容(在匹配到的数字前后加括号)
echo "123" | sed 's/[0-9]*/(&)/'   # 输出:(123)

# 反向引用 \1(交换单词位置)
echo "hello world" | sed 's/\([a-z]*\) \([a-z]*\)/\2 \1/'  # 输出:world hello

# 替换路径时转义 "/"
sed -n 's/\/bin\/bash/\/bin\/sh/p' /etc/passwd

Tip:为了避免转义 / 很繁琐,可以使用 # 或 | 作为分隔符,例如:sed 's#/bin/bash#/bin/sh#'


3.2 删除命令 d

删除匹配到的整行内容。

sed '3d' file        # 删除第3行
sed '2,5d' file      # 删除第2至第5行
sed '/root/d' file   # 删除包含 "root" 的行
sed '/^$/d' file     # 删除空行
sed '/start/,/end/d' # 删除从匹配 "start" 到 "end" 之间的所有行

3.3 追加与插入命令 a / i

  • a (append):在指定行的后面附加新文本。
  • i (insert):在指定行的前面插入新文本。
sed '3a\新行内容' file    # 在第3行后面添加一行
sed '/pattern/i\新行内容' file  # 在匹配到的行前面插入
sed '1i\第一行' file     # 在第一行之前插入

3.4 替换整行命令 c

将匹配到的一整行替换为指定的新文本(注意区分 s 只替换部分内容)。

sed '3c\这是新的一行' file     # 将第3行整行替换
sed '/root/c\管理员账户' file  # 将包含 root 的整行替换

3.5 打印命令 p

通常配合 -n 使用,只打印符合条件的行。

sed -n '3p' file           # 只打印第3行
sed -n '/root/p' file      # 只打印包含 root 的行
sed -n '2,5p' file         # 只打印第2到第5行

3.6 写入与读取文件

  • w:将指定行写入到另一个文件(覆盖/新建)。
  • r:将另一个文件的内容读取并插入到指定行之后。
# 将第3行写入 new.txt
sed '3w new.txt' file

# 将 read.txt 的内容插入到第5行后面
sed '5r read.txt' file

# 将文件内容插入到匹配 "end" 的行后面
sed '/end/r insert.txt' file

4. 地址范围(Address)详解

地址范围用于精确控制 sed 操作应用于哪些行。

写法 含义
空 应用于所有行。
3 仅第3行。
2,5 第2行到第5行。
1~2 从第1行开始,步进为2(即奇数行:1,3,5...)。
$ 最后一行。
/pattern/ 匹配正则表达式的行。
/start/,/end/ 行范围模式。从匹配 start 的行开始,到匹配 end 的行结束(包含首尾)。

组合示例:

sed -n '1~2p' file       # 打印奇数行
sed '$d' file            # 删除最后一行
sed '/^#/d' file         # 删除所有以 # 开头的注释行
sed '/^ftp/,/^mail/d' file # 删除以 ftp 开头到 mail 开头之间的行

5. 多命令执行

如果需要执行多个 sed 命令,可以使用 -e 选项或用分号 ; 分隔。

# 先用 -e 执行两个替换
sed -e 's/old1/new1/g' -e 's/old2/new2/g' file

# 等价于用分号(注意分号前要加反斜杠转义或放在引号内)
sed 's/old1/new1/g; s/old2/new2/g' file

6. 直接修改文件(-i 选项)

# 危险操作:直接修改原文件(无备份)
sed -i 's/old/new/g' file.txt

# 安全做法:修改前自动生成备份文件 file.txt.bak
sed -i.bak 's/old/new/g' file.txt

7. 实战案例集合

需求 命令
去除文件中的空行 sed '/^$/d' file
打印文件第5行 sed -n '5p' file
删除所有行首的空白符 sed 's/^[ \t]*//' file
在每一行行首添加 # sed 's/^/#/' file
将文档中的 "dog" 全部替换为 "cat" sed 's/dog/cat/g' file
删除包含 "error" 的行及其后一行 sed '/error/,+1d' file
将配置文件中的 Port 80 改为 Port 8080 sed -i 's/Port 80/Port 8080/' /etc/service.conf

8. 注意事项(避坑指南)

  1. 区分 s 和 c:s 只替换行内的部分匹配内容;c 是将整行换成全新的文本。
  2. 转义问题:替换内容中包含 /、&、\ 等特殊字符时,记得用 \ 转义,或更换分隔符(如 s#old#new#)。
  3. -i 慎用:线上生产环境建议先不加 -i 预览效果,确认无误后再加 -i.bak 备份修改。
  4. -n 与 p 的组合:如果不加 -n,sed 会默认打印所有行,同时 p 又会重复打印匹配行,导致重复输出。查看特定行时,务必养成加 -n 的习惯。
  5. 正则引擎:sed 默认使用基础正则表达式(BRE),部分元字符(如 +、?、|、{n,m})需加反斜杠 \ 才能生效。若想用扩展正则(ERE),可加 -E 选项(如 sed -E 's/[0-9]+/NUM/g')。

grep 文本搜索过滤

作用:按模式匹配筛选行。

常用选项

选项 说明
-i 忽略大小写
-v 反向匹配(显示不包含模式的行)
-c 统计匹配行数(行数,非次数)
-n 显示匹配行行号
-o 只显示匹配到的字符串(每个单独一行)
-w 匹配整个单词
-A n 显示匹配行及其后 n 行
-B n 显示匹配行及其前 n 行
-C n 显示匹配行及其前后各 n 行
-e 指定多个模式(逻辑 OR)
-q 静默模式,仅通过 $? 判断是否匹配
-E 使用扩展正则(等同于 egrep)
-P 使用 Perl 兼容正则(支持 \d、\s 等)
--color 高亮匹配文本

基本语法

grep [选项] '正则模式' 文件

示例

# 忽略大小写查找 "error"
grep -i error /var/log/messages

# 统计包含 "root" 的行数
grep -c root /etc/passwd

# 显示匹配行及后2行
grep -A 2 'panic' /var/log/syslog

# 匹配整个单词 "bash"
grep -w bash /etc/passwd

# 多个模式(OR)
grep -e 'error' -e 'fail' log.txt

# 静默检查,用于脚本
if grep -q 'success' result.log; then
    echo "成功"
fi
avatar

YeLuo

在代码、学术与分子动力学模拟间穿梭的普通人。近期正埋头于 GROMACS 模拟研究与神经网络计算。

RECOMMENDED

UPLOADTEST benign

2026-10-10T16:51:29

UPLOADTEST benign

2026-10-10T16:51:28

笔记题库

2026-09-24T10:14:03

Table of Contents