Linux 文本处理三剑客:awk、grep、sed 完全指南

Linux 文本处理三剑客:awk、grep、sed 完全指南

1. 概述

Linux 系统提供了三个强大的文本处理工具:awk、grep 和 sed,它们各有所长,结合使用可以高效地处理文本数据。

  • awk:擅长文本分析和格式化输出,是一门强大的脚本语言。
  • grep:擅长文本搜索和过滤。
  • sed:擅长文本编辑和转换。

这三个工具都支持正则表达式,可以处理标准输入和文件输入,是 Shell 脚本编程中不可或缺的工具。


2. awk 使用指南

2.1 基本介绍

awk 是一种编程语言,专门用于文本处理和数据提取,支持变量、条件判断、循环等编程特性。其名称来源于三位创始人的姓氏首字母。

2.2 基本语法

bash 复制代码
awk '模式 { 动作 }' [输入文件...]
命令 | awk '模式 { 动作 }'

2.3 工作原理

awk 按行处理文本,每行被分割成多个字段:

  • $0:整行内容
  • $1:第一个字段
  • $2:第二个字段
  • ...

2.4 常用选项

选项 说明 示例
-F 指定输入字段分隔符 awk -F: '{print $1}' /etc/passwd
-v 定义变量 awk -v var=10 '{print $1 + var}' file
-f 从脚本文件中读取 awk 命令 awk -f script.awk data.txt

2.5 内置变量

变量 说明 示例
FS 输入字段分隔符(默认空格) awk 'BEGIN{FS=":"}{print $1}' file
OFS 输出字段分隔符(默认空格) awk 'BEGIN{OFS="-"}{print $1,$2}' file
RS 输入记录分隔符(默认换行符) awk 'BEGIN{RS=";"}{print}' file
ORS 输出记录分隔符(默认换行符) awk 'BEGIN{ORS="\n\n"}{print}' file
NF 当前行的字段数量 awk '{if(NF>5) print $0}' file
NR 当前处理的总行号 awk '{print NR, $0}' file
FNR 当前文件中的行号 awk '{print FNR, $0}' file1 file2
FILENAME 当前文件名 awk '{print FILENAME, $0}' file

2.6 示例

bash 复制代码
# 打印指定列(源文档示例)
awk '{print $1, $3}' file.txt

# 指定分隔符(源文档示例)
awk -F: '{print $1, $6}' /etc/passwd

# 使用条件过滤(源文档示例)
awk '$3 > 1000 {print $1}' /etc/passwd

# 计算数值总和(源文档示例)
awk '{sum += $1} END {print sum}' file.txt

# 使用BEGIN和END块(源文档示例)
awk 'BEGIN {print "开始处理"} {print $0} END {print "处理完成"}' file.txt

# 使用内置变量(源文档示例)
awk '{print "行号:", NR, "字段数:", NF, "内容:", $0}' file.txt

# 打印雇员信息(源文档示例)
awk '{ print }' employee.txt

# 输出特定行(源文档示例)
awk '/张三/ { print }' employee.txt

# 统计满足特定条件的记录数(源文档示例)
awk '/术/ { count=count+1 } END { print "Count="count }' employee.txt

# 格式化输出表格(源文档综合示例)
awk 'BEGIN { printf "序号\t名字\t部门\t年龄\n-------------------\n" } { print } END {printf "-------------------\n"}' employee.txt

2.7 高级用法

bash 复制代码
# 使用数组统计词频(源文档示例)
awk '{for(i=1;i<=NF;i++) count[$i]++} END {for(word in count) print word, count[word]}' file.txt | sort -k2 -nr

# 条件判断(源文档示例)
awk '{if($3 > 1000) print "用户:", $1, "UID:", $3; else print "系统用户:", $1}' /etc/passwd

# 循环处理(源文档示例)
awk '{for(i=NF;i>=1;i--) printf "%s ", $i; printf "\n"}' file.txt

# 9x9乘法表(源文档示例)
awk 'BEGIN {for(i=1;i<=9;i++){for(j=1;j<=i;j++) printf "%d*%d=%-2d ",j,i,j*i; print}}'

3. grep 使用指南

3.1 基本介绍

grep (Global Regular Expression Print) 用于在文本中搜索匹配指定模式的行。

3.2 基本语法

bash 复制代码
grep [选项] 模式 [文件...]
命令 | grep [选项] 模式

3.3 常用选项

选项 说明 示例
-i 忽略大小写 grep -i 'hello' file.txt
-v 反向匹配,显示不匹配的行 grep -v '^#' config.conf
-n 显示行号 grep -n 'error' logfile.txt
-c 只显示匹配的行数 grep -c 'pattern' data.txt
-r 递归搜索目录 grep -r 'function' /path/to/code/
-l 只显示包含匹配的文件名 grep -l 'TODO' *.py
-E 使用扩展正则表达式 `grep -E '(error
-A n 显示匹配行及其后n行 grep -A 3 'Exception' traceback.log
-B n 显示匹配行及其前n行 grep -B 2 'segmentation fault' system.log
-C n 显示匹配行及其前后各n行 grep -C 2 'keyword' file.txt

3.4 示例

bash 复制代码
# 搜索包含"error"的行(源文档示例)
grep 'error' logfile.txt

# 忽略大小写搜索(源文档示例)
grep -i 'error' logfile.txt

# 显示行号(源文档示例)
grep -n 'error' logfile.txt

# 搜索并显示后3行内容(源文档示例)
grep -A 3 'error' logfile.txt

# 递归搜索目录(源文档示例)
grep -r 'function' /path/to/code/

# 使用扩展正则表达式(源文档示例)
grep -E '(error|warning)' logfile.txt

# 统计文件中包含特定模式的记录数(源文档awk示例的grep等效)
grep -c 'pattern' employee.txt

# 输出总长度大于10的行(源文档awk示例的grep等效)
grep '.\{11,\}' employee.txt

4. sed 使用指南

4.1 基本介绍

sed (Stream EDitor) 是一个流编辑器,用于对文本进行非交互式的编辑。

4.2 基本语法

bash 复制代码
sed [选项] '命令' [输入文件...]
命令 | sed [选项] '命令'

4.3 常用选项

选项 说明 示例
-n 抑制自动输出,只显示处理过的行 sed -n '10p' file.txt
-e 允许多个编辑命令 sed -e 's/foo/bar/' -e '/baz/d' file
-i 直接修改文件内容 sed -i.bak 's/old/new/g' file.txt
-r 使用扩展正则表达式 `sed -r 's/(foo bar)/YES/g' file`

4.4 常用命令

命令 说明 示例
s/模式/替换/标志 替换操作 sed 's/old/new/g' file.txt
p 打印 sed -n '1,5p' file.txt
d 删除 sed '/pattern/d' file.txt
a\文本 在行后追加文本 sed '$a\追加到最后一行' file.txt
i\文本 在行前插入文本 sed '1i\插入到第一行' file.txt
c\文本 替换整行 sed '/pattern/c\新的整行内容' file.txt

4.5 示例

bash 复制代码
# 替换文本(源文档示例)
sed 's/old/new/g' file.txt

# 删除空行(源文档示例)
sed '/^$/d' file.txt

# 直接修改文件(源文档示例)
sed -i 's/old/new/g' file.txt

# 打印特定行(源文档示例)
sed -n '10,20p' file.txt

# 多重编辑(源文档示例)
sed -e 's/foo/bar/g' -e '/baz/d' file.txt

# 在匹配行后追加内容(源文档示例)
sed '/pattern/a\追加的内容' file.txt

# 模拟cat命令打印文件内容(源文档示例)
sed '' data.txt

# 从标准输入中读取数据(源文档示例)
echo "hello world" | sed ''

# 使用脚本文件(源文档示例)
echo -e "1d\n2d\n5d" > scripts
sed -f scripts data.txt

5. 综合应用示例

5.1 日志分析

bash 复制代码
# 分析日志中的错误,统计每种错误的数量(源文档grep示例扩展)
grep 'ERROR' application.log | awk '{print $5}' | sort | uniq -c | sort -nr

# 提取最近一小时的日志并分析(源文档sed示例扩展)
sed -n "/$(date -d '1 hour ago' '+%H:%M:%S')/,\$p" application.log | grep 'ERROR' | awk '{print $5}' | sort | uniq -c

5.2 数据提取和转换

bash 复制代码
# 从CSV文件中提取特定列并转换格式(源文档awk示例扩展)
awk -F, '{print $1 "," $3 "," $5}' data.csv | sed 's/旧值/新值/g' > processed_data.csv

# 提取网页中的链接(源文档grep示例扩展)
curl -s http://example.com | grep -o 'href="[^"]*"' | sed 's/href="//;s/"$//' | awk '!/^#/ && !/^javascript:/'

# 生成格式化的文本报告(源文档awk综合示例扩展)
awk 'BEGIN {printf "序号\t名字\t部门\t年龄\n-------------------\n"} {printf "%s\t%s\t%s\t%s\n", $1, $2, $3, $4} END {printf "-------------------\n"}' employee.txt

5.3 系统监控

bash 复制代码
# 监控进程内存使用(源文档awk示例扩展)
ps aux | awk '{if($4 > 5.0) print "进程:", $11, "内存使用:", $4"%"}'

# 分析磁盘使用情况(源文档awk示例扩展)
df -h | awk '/\/dev\/sd/ {print "分区:", $1, "使用率:", $5, "可用空间:", $4}'

# 检查系统用户(源文档awk示例扩展)
awk -F: '$3 < 1000 {print "系统用户:", $1} $3 >= 1000 {print "普通用户:", $1}' /etc/passwd

6. 正则表达式参考

6.1 基本元字符

元字符 说明
. 匹配任意单个字符
* 匹配前一个字符0次或多次
+ 匹配前一个字符1次或多次
? 匹配前一个字符0次或1次
^ 匹配行首
$ 匹配行尾
[] 匹配括号内的任意字符
[^] 不匹配括号内的任意字符
` `
() 分组

6.2 字符类

字符类 说明
[[:alpha:]] 字母字符
[[:digit:]] 数字字符
[[:alnum:]] 字母数字字符
[[:space:]] 空白字符
[[:lower:]] 小写字母
[[:upper:]] 大写字母

6.3 转义字符

转义序列 说明
\n 换行符
\t 制表符
\s 空白字符
\S 非空白字符
\w 单词字符
\W 非单词字符
\d 数字字符
\D 非数字字符

7. 总结与速查

7.1 工具选择指南

  • 搜索文本:使用 grep
  • 编辑文本:使用 sed
  • 处理结构化数据:使用 awk
  • 复杂文本处理:结合使用三者

7.2 常用命令速查

awk 常用命令

bash 复制代码
awk '{print $1}' file                 # 打印第一列
awk -F: '{print $1}' file             # 指定冒号分隔符并打印第一列
awk 'NR==10' file                     # 打印第10行
awk '$1 > 100' file                   # 过滤第一列大于100的行
awk '{sum+=$1} END{print sum}' file   # 对第一列求和
awk 'BEGIN{FS=":";OFS="-"}{print $1,$3}' file # 设置输入输出分隔符并打印
awk '/pattern/{count++} END{print count}' file # 统计模式出现次数

grep 常用命令

bash 复制代码
grep pattern file                     # 基本搜索
grep -i pattern file                  # 忽略大小写
grep -v pattern file                  # 反向匹配
grep -n pattern file                  # 显示行号
grep -r pattern dir                   # 递归搜索
grep -E "pattern1|pattern2" file      # 扩展正则表达式(或)
grep -c pattern file                  # 统计匹配行数
grep -A n pattern file                # 显示匹配行及后n行

sed 常用命令

bash 复制代码
sed 's/old/new/g' file                # 全局替换
sed '/pattern/d' file                 # 删除匹配行
sed -n '10,20p' file                  # 打印10-20行
sed -i.bak 's/old/new/' file          # 直接修改文件并备份原文件
sed '/^#/d; /^$/d' file               # 删除注释和空行
sed '1,5s/old/new/g' file             # 替换1-5行的内容
sed '/pattern/a\text' file            # 在匹配行后追加文本

7.3 性能优化技巧

  • 尽量使用最简单的正则表达式
  • 在 grep 中使用 -F 选项处理固定字符串
  • 在 awk 中预先处理数据减少后续操作
  • 使用管道连接多个简单操作而不是一个复杂操作
  • 对于大文件,考虑使用 split 分割后并行处理

7.4 常见问题解决

  • 特殊字符处理 :使用转义字符或不同的定界符(如 s#old#new#
  • 跨行匹配 :使用 sed 的 ND 命令或 awk 的 RS 变量
  • 性能问题:优化正则表达式,减少回溯
  • 编码问题:确保终端和文件编码一致

通过掌握这三款工具的组合使用,可以解决 Linux 环境下绝大多数文本处理需求,大大提高工作效率。本文档涵盖了源文档中的主要示例和用法,并添加了选项示例,可以作为日常参考和学习的指南。

相关推荐
朱皮皮呀24 分钟前
Spring Cloud——服务注册与服务发现原理与实现
运维·spring cloud·eureka·服务发现·php
xixingzhe239 分钟前
多人同时导出 Excel 导致内存溢出
服务器·设计
吱吱企业安全通讯软件39 分钟前
吱吱企业通讯软件保证内部通讯安全,搭建数字安全体系
大数据·网络·人工智能·安全·信息与通信·吱吱办公通讯
云手机掌柜44 分钟前
Tumblr长文运营:亚矩阵云手机助力多账号轮询与关键词布局系统
大数据·服务器·tcp/ip·矩阵·流量运营·虚幻·云手机
yuanpan2 小时前
ubuntu系统上的conda虚拟环境导出方便下次安装
linux·ubuntu·conda
云边云科技2 小时前
零售行业新店网络零接触部署场景下,如何选择SDWAN
运维·服务器·网络·人工智能·安全·边缘计算·零售
城管不管2 小时前
Docker核心---数据卷(堵门秘籍)
运维·docker·容器
rainFFrain2 小时前
Boost搜索引擎项目(详细思路版)
网络·c++·http·搜索引擎
Gavin_9153 小时前
从零开始部署经典开源项目管理系统最新版redmine6-Linux Debian12
linux·ruby on rails·开源·debian·ruby·redmine