Linux文本处理三剑客:grep、sed和awk

2025-01-17T22:19:28+08:00 | 6分钟阅读

bestzy
Linux文本处理三剑客:grep、sed和awk

Linux系统中的grep、sed和awk是三个强大的文本处理工具,它们各自具有独特的功能和应用场景。本文将详细介绍这三个命令的使用方法和常见应用场景。

grep - 文本搜索利器

grep(Global Regular Expression Print)命令用于在文件中搜索指定的文本模式。它是最基础也是最常用的文本搜索工具,默认是按行搜索的。

基本语法

grep [选项] 模式 文件名

常用选项

选项说明示例示例说明
-i忽略大小写grep -i "Error" file.txt忽略“Error”的大小写
-v显示不匹配的行grep -v "error" file.txt显示不匹配“error”的行
-n显示行号grep -n "error" file.txt显示匹配行及其行号,如 “123:error occurred”
-l只显示包含匹配的文件名grep -l "error" *.txt只列出包含 “error” 的文件名,如 “log.txt”
-L只显示不包含匹配的文件名grep -L "error" *.txt只列出不包含 “error” 的文件名,如 “success.txt”
-c只显示匹配行的数量grep -c "error" file.txt显示文件中包含 “error” 的行数,如 “5”
-w只匹配整个单词grep -w "error" file.txt匹配 “error” 但不匹配 “errors” 或 “errorlog”
-x只匹配整行(精确匹配整行grep -x "error" file.txt只匹配整行恰好是 “error” 的行,不匹配 “error log”
-r递归搜索目录(不跟随符号链接)grep -r "error" /path在 /path 目录下递归搜索,不包含符号链接指向的目录
-R递归搜索(跟随符号链接)grep -R "error" /path在 /path 目录下递归搜索,包含符号链接指向的目录
-A n显示匹配行及后 n 行grep -A 2 "error" file.txt显示包含 “error” 的行及其后 2 行
-B n显示匹配行及前 n 行grep -B 2 "error" file.txt显示包含 “error” 的行及其前 2 行
-C n显示匹配行及前后各 n 行grep -C 2 "error" file.txt显示包含 “error” 的行及其前后各 2 行

grep 可以组合使用多个选项,例如:

# 忽略大小写 + 显示行号
grep -in "error" file.txt

# 递归搜索 + 显示行号 + 只显示文件名
grep -rln "error" /path/to/dir

# 显示行号 + 匹配整词 + 显示上下文
grep -nw -C 2 "error" file.txt

使用示例

# 在文件中搜索包含"error"的行
grep "error" log.txt

# 忽略大小写搜索
grep -i "ERROR" log.txt

# 显示行号
grep -n "error" log.txt

# 递归搜索目录
grep -r "TODO" ./src/

# 使用正则表达式
grep "^[0-9]" data.txt

sed - 流编辑器

sed(Stream Editor)是一个强大的文本流编辑器,可以对文本进行替换、删除、插入等操作。

基本语法

sed [选项] '[地址]命令[参数]' 文件名
  • 地址:指定要操作的行(可选),可以是
    • 行号(如 1 表示第1行,$ 表示最后一行)
    • 正则表达式(如 /pattern/ 表示匹配 pattern 的行)
    • 行范围(如 1,5 表示第1到第5行)
  • 命令:指定要执行的操作(必选),常用命令有s、d、p等。
  • 参数:命令的附加参数(可选),用于进一步控制命令的行为,比如:
    • g:全局替换(用于 s 命令)。
    • 2:只替换第2个匹配(用于 s 命令)。
    • i:忽略大小写(用于正则表达式)。

常用选项

  • -i: 直接修改文件内容(慎用,会覆盖原文件)。
  • -n: 禁止自动输出,只打印被处理的行(通常与 p 命令一起使用)。
  • -e: 执行多个命令
  • -f: 从文件读取命令

常用命令

命令解释说明是否需要分隔符常见使用方式常见使用方式解释
ssubstitute替换sed ’s/old/new/’ 文件s 后面的 /old/new/替换命令的具体内容,它定义了替换操作的细节,s命令的完整格式是s<分隔符>查找模式<分隔符>替换内容<分隔符>s/old/new/中地址是隐式的,表示所有行
ddelete删除sed ‘/pattern/d’ 文件/pattern/为地址部分,是 sed 中的地址匹配语法,pattern是一个正则表达式;命令为d
pprint打印sed -n ‘/pattern/p’ 文件/pattern/为地址部分,是 sed 中的地址匹配语法,pattern是一个正则表达式;命令为p
iinsert在匹配行之前插入内容sed ‘/pattern/i 新内容’ 文件/pattern/为地址部分,是 sed 中的地址匹配语法,pattern是一个正则表达式;命令为i
aappend在匹配行之后追加内容sed ‘/pattern/a 新内容’ 文件/pattern/为地址部分,是 sed 中的地址匹配语法,pattern是一个正则表达式;命令为a
cchange用新内容替换整行sed ‘/pattern/c 新内容’ 文件/pattern/为地址部分,是 sed 中的地址匹配语法,pattern是一个正则表达式;命令为c

注意,s命令的默认分隔符/,但可以使用其他符号(如 |: 等)作为分隔符,当/有其他作用时,如表示文件路径,可以使用自定义分隔符。示例:

# 使用默认分隔符
sed 's/old/new/' file.txt

# 使用自定义分隔符
sed 's|old|new|' file.txt
sed 's:old🆕' file.txt

使用示例

# 替换文本
sed 's/old/new/' file.txt
sed 's/old/new/g' file.txt  # 全局替换

# 删除空行
sed '/^$/d' file.txt

# 打印特定行
sed -n '1,5p' file.txt

# 直接修改文件
sed -i 's/old/new/g' file.txt

# 多个命令组合
sed -e 's/old/new/' -e 's/foo/bar/' file.txt

awk - 文本处理编程语言

awk是一个强大的文本处理编程语言,特别适合处理格式化的文本数据。

基本语法

awk [选项] '模式 {动作}' 文件名
  • 模式 pattern:决定何时执行action
  • 动作 action:在pattern匹配时要执行的操作

常用选项

选项说明示例示例说明
-F指定字段分隔符awk -F: '{ print $1 }' /etc/passwd使用冒号作为分隔符
-f从文件读取 awk 脚本awk -f script.awk data.txt从 script.awk 读取脚本
-v设置变量awk -v name="John" '{ print name }' file.txt设置变量 name 的值为 “John”

常用内置变量

内置变量让我们能更方便地处理文本和控制程序行为

变量名称说明使用示例使用示例说明
$0整行内容awk '{ print $0 }' file.txt打印文件的每一行内容
$1,$2…第n个字段awk '{ print $1, $3 }' file.txt打印每行的第1和第3个字段
NF字段数量awk '{ print NF, $0 }' file.txt打印每行的字段数量及内容
NR当前行号awk '{ print "Line " NR ":", $0 }' file.txt打印行号和行内容
FS输入字段分隔符awk 'BEGIN { FS=":" } { print $1 }' /etc/passwd使用冒号作为分隔符读取passwd文件
OFS输出字段分隔符awk 'BEGIN { OFS=" -> " } { print $1, $2 }' file.txt输出字段之间使用 " -> " 分隔
RS记录分隔符awk 'BEGIN { RS="" } { print $0 }' file.txt使用空行作为记录分隔符(段落模式)

模式类型

正则表达式模式

在 awk 中,正则表达式模式需要用 / 包裹。

# 匹配包含 "error" 的行
awk '/error/ { print $0 }' log.txt

# 匹配以 "root" 开头的行
awk '/^root/ { print $0 }' /etc/passwd

关系表达式模式

# 第三列大于 100
awk '$3 > 100 { print $0 }' data.txt

# 第一列等于 "admin"
awk '$1 == "admin" { print $0 }' users.txt

复合模式

复合模式是通过逻辑运算符(&&||!)组合多个条件来创建更复杂的匹配规则。

# 第一列是 "error" 且第四列大于 100
awk '$1 == "error" && $4 > 100 { print $0 }' log.txt

# 第二列小于 50 或大于 100
awk '$2 < 50 || $2 > 100 { print $0 }' data.txt

特殊模式

# BEGIN:在处理第一行之前执行
# END:在处理完最后一行后执行
awk '
BEGIN { print "Start processing" }
      { print $0 }
END   { print "End processing" }
' file.txt

动作的常见用途

打印操作

# 直接打印整行
{ print $0 }

# 打印特定字段
{ print $1, $3 }

# 格式化打印
{ printf "Name: %s, Age: %d\n", $1, $2 }

计算操作

# 累加第一列的值
{ sum += $1 }
END { print "总和:", sum }

# 计算平均值
{
    total += $1
    count++
}
END {
    print "平均值:", total/count
}

条件处理

# 如果第二列大于60,打印"及格"
{
    if ($2 > 60) {
        print "及格"
    } else {
        print "不及格"
    }
}

使用示例

# 打印特定列
awk '{print $1, $3}' file.txt

# 使用自定义分隔符
awk -F: '{print $1}' /etc/passwd

# 条件过滤
awk '$3 > 100 {print $0}' data.txt

# 计算总和
awk '{sum += $1} END {print sum}' numbers.txt

# 统计行数
awk 'END {print NR}' file.txt

# 复杂处理示例
awk '
    BEGIN {
        print "开始处理..."
        sum = 0
    }
    $1 > 0 {
        sum += $1
        count++
    }
    END {
        printf "平均值: %.2f\n", sum/count
    }
' data.txt

实用组合示例

grepsedawk命令经常结合使用,能够实现更强大的文本处理功能:

# 查找并替换
grep "pattern" file.txt | sed 's/old/new/g'

# 过滤并统计
grep "error" log.txt | awk '{count[$3]++} END {for(i in count) print i, count[i]}'

# 复杂日志分析
awk '/ERROR/ {print $0}' log.txt | sed 's/ERROR/严重错误/g' | grep "2024"

总结

  • grep适合文本搜索和过滤
  • sed适合文本替换和编辑
  • awk适合复杂的文本处理和数据分析

这三个命令各有特色,组合使用可以解决绝大多数文本处理需求。

© 2025 Bestzy's Blog

🌱 Powered by Hugo with theme Dream.

About Me

👋 Hi, This is Zheng Yi.