十三、Linux Shell脚本:文本处理三剑客之 sed 与 awk

本文涉及的产品
可观测可视化 Grafana 版,10个用户账号 1个月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
函数计算FC,每月15万CU 3个月
简介: 如果说grep是文本处理的“探照灯”,那sed和awk就是“手术刀”和“瑞士军刀”。sed 擅长按行“动手术”,可以轻松地删除、打印或替换特定行的内容,尤其是它的替换功能(s/.../.../)非常强大。而 awk 更厉害,它天生就能看懂按列(字段)分布的数据,像个小型的Excel。你可以让它只打印某几列,或者根据某一列的值做计算和判断,特别适合生成统计报告。

在掌握grep和正则表达式之后,我们接着学习Linux命令行文本处理的另外两大核心工具:sed 和 awk 。grep 擅长查找,而 sed 擅长编辑,awk 则擅长格式化报告和复杂的数据处理。

一、流编辑器 sed

sed 是一个非交互式流编辑器。它逐行读取文本,根据预设规则每行进行处理,并将结果输出标准输出默认不修改原始文件。

基本语法: sed [选项] '地址 命令' 文件名

  • 地址: 指定操作的行。可以是行号 (如 3)、范围 (如 2,5) 或正则表达式 (如 /pattern/)。若省略,则应用于所有行

常用命令:

1. d (delete) - 删除行

# 删除文件的第3行
sed '3d' /etc/passwd

# 删除文件第2到第5行
sed '2,5d' /etc/passwd

# 删除所有包含 "nologin" 字符串的行
sed '/nologin/d' /etc/passwd

2. p (print) - 打印行

p 命令通常与 -n 选项配合使用-n禁止 sed默认输出,从而只打印p 命令明确指定的行。

# 只打印文件的第3行
sed -n '3p' /etc/passwd

# 只打印包含 "root" 的行 (效果类似 grep)
sed -n '/root/p' /etc/passwd

3. s (substitute) - 替换

这是 sed 最强大的命令。
语法: 's/pattern/replacement/flags'

pattern: 要匹配的正则表达式。
replacement: 要替换成的字符串。& 符号在replacement代表被匹配到的整个内容
flags:
g: 全局替换行内的所有匹配
i: 忽略大小写
数字 (如 2): 只替换每行中第 N 次出现的匹配。

代码示例:

# 将每行第一个 "root" 替换为 "admin"
sed 's/root/admin/' /etc/passwd

# 将所有 "nologin" 替换为 "disabled"
sed 's/nologin/disabled/g' /etc/passwd

# 给所有数字加上方括号
echo "line 123 has number 456" | sed 's/[0-9][0-9]*/[&]/g'

# 使用 -i 选项直接修改文件 (危险操作,建议先备份)
sed -i.bak 's/old_text/new_text/g' /path/to/your/file
# (-i.bak 会创建一个 .bak 后缀的备份文件)

二、报告生成器 awk

awk 是一个强大文本处理语言,它逐行读取输入,并将每行分隔符切分字段极度擅长处理列式数据生成报告

基本语法: awk '[选项] 'pattern { action }' 文件名

核心概念:

Record: 默认情况下,每行是一个记录。
Field: 每个记录分隔符切分成的部分。通过 $1, $2, $3 ... 引用,$0 代表整行
FS: 输入字段分隔符
NR: 当前记录行号
NF: 当前记录字段数量

Pattern (模式): 决定是否对当前行执行 action。可以是正则表达式条件表达式特殊的 BEGIN / END
Action (动作): 花括号 {} 中包含的一系列命令

常用命令与功能:

1. 打印指定字段

# 打印 /etc/passwd 文件的第一列 (用户名)
awk -F: '{print $1}' /etc/passwd

# 打印 /etc/passwd 文件的第一列和最后一列
awk -F: '{print "User:", $1, "| Shell:", $NF}' /etc/passwd
  • -F:: 指定字段分隔符为冒号

2. 使用模式进行过滤

# 只打印包含 "root" 的行
awk '/root/' /etc/passwd

# 只打印第三个字段(UID)小于10的行
awk -F: '$3 < 10 {print $0}' /etc/passwd

# 只打印奇数行
awk 'NR % 2 == 1' /etc/passwd

3. 使用 BEGINEND 模式

  • BEGIN { ... }: 在处理任何行之前执行,用于初始化打印表头
  • END { ... }: 在处理完所有行之后执行,用于计算汇总打印结果

代码示例:

# 统计 /etc/passwd 文件的用户总数
awk 'END {print "Total users:", NR}' /etc/passwd

# 打印磁盘使用情况报告,并添加表头
df -h | awk 'BEGIN {printf "%-30s %-10s %-10s\n", "Filesystem", "Size", "Used%"} NR>1 {printf "%-30s %-10s %-10s\n", $1, $2, $5}'

三、总结

本次我们深入学习了Linux文本处理三剑客中的sedawksed 作为流编辑器,其核心优势在于对文本行进行删除、打印和替换操作。而awk 则更像一个微型编程语言,它按字段处理数据,擅长结构化文本提取信息、计算、生成格式化报告。在实际工作中,经常将 grep, sed, awk 通过管道组合使用,以完成复杂文本处理任务


练习题

背景文件 server.log 内容:

2024-08-08 10:00:15 INFO: User 'alice' logged in from 192.168.1.10.
2024-08-08 10:02:30 DEBUG: System check initiated.
2024-08-08 10:03:05 WARNING: Disk space is running low on /dev/sda1.
2024-08-08 10:05:45 INFO: User 'bob' accessed resource 'file.txt'.
2024-08-08 10:06:22 ERROR: Failed to connect to database 'prod_db'.

题目:

  1. sed删除: 使用 sed 命令,删除 server.log 中所有 DEBUG 级别的日志行。
  2. sed打印: 使用 sed 命令,只打印出 server.log 文件的第 2 到第 4 行。
  3. sed替换: 使用 sed 命令,将 server.log 中所有出现的 "User" (首字母大写) 替换为 "Client"。
  4. awk打印字段: server.log日志级别是第3个字段 (以空格为分隔符)。请使用 awk 命令,打印出所有日志行的日期 (第1个字段) 和日志级别
  5. awk模式匹配: 使用 awk 命令,只打印 server.log 中包含 ERROR 信息的完整日志行
  6. awk内置变量: 使用 awk 命令,打印 server.log字段数超过8个的所有行。
  7. awk BEGIN/END: 使用 awk 命令,统计 server.logINFO, WARNING, ERROR 日志各自出现的次数。
  8. sed综合: 写一条 sed 命令,将 server.log 中所有 INFO 日志行的行首添加 [INFO_LOG] 前缀。
  9. awk与sed组合: 使用管道,先用 sed 过滤出 server.log 中所有 INFO 级别的日志,然后用 awk 提取并打印出用户名 (假设用户名总是在单引号 ' ' 中)。
  10. sed替换指定出现次数: 写一条 sed 命令,只替换 server.log 中每行第二次出现的冒号 : 为分号 ;

答案与解析

  1. sed删除:

    sed '/DEBUG:/d' server.log
    
    • 解析: '/DEBUG:/d' 使用正则表达式 /DEBUG:/ 作为地址,匹配所有包含 "DEBUG:" 的行,并用 d 命令删除它们。
  2. sed打印:

    sed -n '2,4p' server.log
    
    • 解析: -n 禁止默认输出2,4行号范围地址,p 命令只打印这个范围内的行。
  3. sed替换:

    sed 's/User/Client/g' server.log
    
    • 解析: s/User/Client/g所有出现的 "User" 替换为 "Client"。g 标志确保全局替换。
  4. awk打印字段:

    awk '{print $1, $3}' server.log
    
    • 解析: awk 默认以空格或制表符为分隔符。$1 是日期,$3 是日志级别。{print $1, $3} 打印这两个字段。
  5. awk模式匹配:

    awk '/ERROR/' server.log
    
    • 解析: awk模式部分如果没有对应的 { action },则默认动作就是 {print $0} (打印整行)。/ERROR/ 匹配包含 "ERROR" 的行。
  6. awk内置变量:

    awk 'NF > 8' server.log
    
    • 解析: NF > 8 是一个条件模式NF当前行的字段数。只有当字段数大于8时,条件为真,执行默认的打印整行动作。
  7. awk BEGIN/END:

    awk '/INFO/ {info_count++} /WARNING/ {warn_count++} /ERROR/ {error_count++} END {print "INFO:", info_count, "WARNING:", warn_count, "ERROR:", error_count}' server.log
    
    • 解析: awk 可以有多个 pattern { action } 组合。它会遍历每一行,匹配对应的模式并执行动作 (累加计数器)。END 块在最后打印所有计数器的汇总结果
  8. sed综合:

    sed '/INFO/s/^/[INFO_LOG] /' server.log
    
    • 解析: /INFO/地址,表示只对包含 "INFO" 的行执行命令。s/^/[INFO_LOG] /替换命令^ 匹配行首,将其替换为指定的前缀。
  9. awk与sed组合:

    sed -n '/INFO/p' server.log | awk -F"'" '{print $2}'
    

    解析:

    • sed -n '/INFO/p' server.log: 首先过滤出所有INFO日志行。
    • |: 管道将结果传给awk
    • awk -F"'" '{print $2}': awk 使用单引号 '' 作为字段分隔符 (-F"'"), 这样用户名就正好是第二个字段 $2
  10. sed替换指定出现次数:

    sed 's/:/;/2' server.log
    
    • 解析: s/pattern/replacement/flags 中的 flags 可以是一个数字2 表示只替换每行中第二次出现的匹配项。
目录
相关文章
|
2月前
|
监控 Shell Linux
十、Linux Shell脚本:流程控制语句
要让脚本从简单的“指令清单”升级为能干的“小助手”,就需要用if教它根据条件做判断,用for和while循环让它重复处理任务,再用case语句帮它在多个选项中做出清晰的选择
259 1
|
2月前
|
分布式计算 Java 关系型数据库
二、Sqoop 详细安装部署教程
在大数据开发实战中,Sqoop 是数据库与 Hadoop 生态之间不可或缺的数据传输工具。这篇文章将以 Sqoop 1.4.7 为例,结合官方站点截图,详细讲解 Sqoop 的下载路径、安装步骤、环境配置,以及常见 JDBC 驱动的准备过程,帮你一步步搭建出能正常运行的 Sqoop 环境,并通过 list-databases 命令验证安装是否成功。如果你正打算学习 Sqoop,或者在搭建大数据平台过程中遇到安装配置问题,本文将是非常实用的参考指南。
163 6
|
2月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
376 1
二、Linux文本处理与文件操作核心命令
|
Kubernetes 容器 Perl
k8s查看日志命令—2023.02
k8s查看日志命令—2023.02
423 0
|
2月前
|
安全 Linux Shell
四、Linux核心工具:Vim, 文件链接与SSH
要想在Linux世界里游刃有余,光会“走路”还不够,还得配上几样“高级装备”。首先是Vim编辑器,它像一把瑞士军刀,让你能在命令行里高效地修改文件。然后要懂“软硬链接”,软链接像个快捷方式,硬链接则是给文件起了个别名。最后,SSH是你的“传送门”,不仅能让你安全地远程登录服务器,还能用scp轻松传输文件,设置好密钥更能实现免-密登录,极大提升效率。
342 4
|
2月前
|
存储 安全 Linux
三、Linux用户与权限管理详解
管理Linux系统就像当一个大楼的管家。首先,你得用useradd和passwd给新员工发“钥匙”(创建用户并设密码),并用groupadd把他们分到不同“部门”(用户组)。然后,你要为每个“房间”(文件或目录)设定规矩,这就是文件权限:用chmod命令设置谁(所有者、同部门、其他人)可以“进入”(x)、“读取”(r)或“写入”(w)。最后,用chown还能把房间的归属权转让给别人。
405 3
|
2月前
|
人工智能 Java API
Java AI智能体实战:使用LangChain4j构建能使用工具的AI助手
随着AI技术的发展,AI智能体(Agent)能够通过使用工具来执行复杂任务,从而大幅扩展其能力边界。本文介绍如何在Java中使用LangChain4j框架构建一个能够使用外部工具的AI智能体。我们将通过一个具体示例——一个能获取天气信息和执行数学计算的AI助手,详细讲解如何定义工具、创建智能体并处理执行流程。本文包含完整的代码示例和架构说明,帮助Java开发者快速上手AI智能体的开发。
885 8
|
1月前
|
安全 数据可视化 开发者
有什么值得推荐的网站源码分享下载?
本文指出开发者找优质安全网站源码耗时,介绍了多种获取渠道:有 GitHub 等综合开源社区,虽资源多但新手筛选难;有垂直领域平台,其中 PageAdmin CMS 系统因源码完整、易上手、扩展性强受青睐;还有贴合国内需求的国内社区。同时提醒注意版权与安全检测,助力开发者高效搭建项目。
409 9
|
2月前
|
IDE Java 关系型数据库
Java 初学者学习路线(含代码示例)
本教程为Java初学者设计,涵盖基础语法、面向对象、集合、异常处理、文件操作、多线程、JDBC、Servlet及MyBatis等内容,每阶段配核心代码示例,强调动手实践,助你循序渐进掌握Java编程。
350 3