当前位置: 首页 > news >正文

Linux三剑客:grep、sed、awk 详解以及find区别

grep、sed、awk是Linux/Unix系统中经典的文本处理工具,合称“三剑客”。三者各有所长:

  • grep:擅长文本搜索(过滤)。
  • sed:擅长文本编辑(替换、删除等)。
  • awk:擅长文本分析(格式化输出、计算等)

一、grep:文本搜索

1. 基本语法

  • 用途​​:在​​文件内容​​中搜索匹配特定模式的文本(支持正则表达式)。
  • ​工作对象​​:文件内容(文本)。
  • 常用选项​​:
    选项作用示例
    -i忽略大小写grep -i "error" file.log
    -r递归搜索目录grep -r "TODO" ./src
    -n显示匹配行的行号grep -n "warning" app.log
    -v反向匹配(输出​​不包含​​模式的行)grep -v "debug" output.log
    -l仅输出包含匹配项的文件名grep -rl "FIXME" ./code
    -E启用扩展正则表达式(等价于egrep`grep -E "err

2. 示例

我们假设存在名为file.txt的文件,对该文件进行grep命令操作,文件内容如下

hello world
Hello Universe
start here
mission complete
hallo and hello
goodbye end

执行以下命令:

# 在文件中搜索基础文本
grep "hello" file.txt           # 输出:hello world, hallo and hello
grep -i "hello" file.txt        # 输出:hello world, Hello Universe, hallo and hello
grep -n "hello" file.txt        # 输出:1:hello world, 5:hallo and hello# 递归搜索目录
grep -r "TODO" ./src            # 搜索./src目录下所有文件中的"TODO"# 使用正则表达式
grep "^start" file.txt          # 搜索以start开头的行 → "start here"
grep "end$" file.txt            # 搜索以end结尾的行 → "goodbye end"
grep "he[ae]llo" file.txt       # 匹配hello或hallo → "hello world", "hallo and hello"
grep -E "hello|complete" file.txt  # 匹配hello或complete → "hello world", "mission complete", "hallo and hello"
grep "[A-Z]" file.txt           # 搜索包含大写字母的行 → "Hello Universe", "mission complete"

二、sed:文本替换与转换​

​1. 基本语法​

  • ​用途​​:对输入流(文件或管道)进行​​文本替换、删除、插入、打印​​等操作

  • ​工作模式​​:逐行处理文本,默认输出到标准输出(不修改源文件)

  • ​常用选项​​:

    选项作用示例
    -e指定编辑命令sed -e 's/a/A/' file
    -n抑制默认输出(常与p命令配合)sed -n '1,3p' file
    -i原地修改文件(可选备份后缀)sed -i.bak 's/old/new/' file
    -r启用扩展正则表达式sed -r 's/(abc)/\U\1/' file
  • ​常用命令​​:

    命令作用示例
    s/regex/replacement/替换匹配的文本sed 's/old/new/' file
    d删除行sed '3d' file
    p打印行sed -n '1,5p' file
    a\text在行后追加文本sed '2a\new line' file
    i\text在行前插入文本sed '3i\inserted' file
    y/abc/ABC/字符转换(类似tr)sed 'y/a-z/A-Z/' file

​2. 示例​

假设存在名为 demo.txt 的文件,内容为:

hello world
Hello Universe
start here
mission complete
hallo and hello
goodbye end

​基础操作​​:

# 1. 替换文本(每行第一个匹配)
sed 's/hello/HELLO/' demo.txt
# 输出:
# HELLO world
# Hello Universe
# start here
# mission complete
# hallo and HELLO
# goodbye end# 2. 全局替换(使用g标志)
sed 's/hello/HELLO/g' demo.txt
# 输出:
# HELLO world
# Hello Universe
# start here
# mission complete
# hallo and HELLO
# goodbye end# 3. 删除行(删除第3行)
sed '3d' demo.txt
# 输出:
# hello world
# Hello Universe
# mission complete
# hallo and hello
# goodbye end# 4. 打印特定行(打印2-4行)
sed -n '2,4p' demo.txt
# 输出:
# Hello Universe
# start here
# mission complete

​正则表达式操作​​:

# 1. 替换以"s"开头的行
sed '/^s/ s/here/HERE/' demo.txt
# 输出:第三行 → start HERE# 2. 删除包含"complete"的行
sed '/complete/d' demo.txt
# 输出中无第四行# 3. 在"hallo"行前插入文本
sed '/hallo/i\--INSERT BEFORE--' demo.txt
# 在第五行前插入:--INSERT BEFORE--# 4. 在"goodbye"行后追加文本
sed '/goodbye/a\--APPEND AFTER--' demo.txt
# 在第六行后追加:--APPEND AFTER--

​高级操作​​:

# 1. 使用反向引用(保留部分内容)
echo "2023-01-15" | sed -r 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3.\2.\1/'
# 输出:15.01.2023# 2. 仅修改第2-4行
sed '2,4 s/o/O/g' demo.txt
# 输出:
# hello world
# HellO Universe
# start here
# missiOn cOmplete
# hallo and hello
# goodbye end# 3. 多重操作(使用-e)
sed -e 's/hello/HELLO/' -e '3d' demo.txt
# 先替换hello再删除第3行# 4. 字符转换(小写转大写)
sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' demo.txt
# 全转大写

​文件操作​​:

# 1. 修改文件并备份(GNU sed)
sed -i.bak 's/hello/HELLO/g' demo.txt  # 生成demo.txt.bak备份# 2. 直接修改文件(无备份)
sed -i 's/hello/HELLO/g' demo.txt

​3. 使用技巧​

  1. ​测试命令​​:先用不带 -i 的命令测试,确认无误后再用 -i
  2. ​转义特殊字符​​:对 /&. 等使用反斜杠转义
  3. ​跨行处理​​:使用 N 命令读入多行(如 sed 'N; s/\n//'
  4. ​组合命令​​:用分号分隔多个命令 sed 's/a/A/; 3d' file

⚠️ ​​警告​​:使用 -i 时务必先备份,避免不可逆的数据丢失!

​三、awk:文本分析​

​1. 基本语法​

  • ​用途​​:对文本进行​​模式扫描和处理​​,适用于结构化的文本数据(如按列处理)

  • ​工作模式​​:逐行扫描文件,对匹配模式的每行执行指定动作(默认动作为打印当前行)

  • ​核心概念​​:

    • ​字段(Field)​​:通过分隔符自动拆分的文本单元($1$2...表示)
    • ​记录(Record)​​:默认以换行符分隔的行(可通过RS变量修改)
  • ​语法结构​​:

    awk '模式 {动作}' 文件名
    # 或使用单行命令
    awk -F: '{print $1}' /etc/passwd
  • ​常用内置变量​​:

    变量作用示例
    $0整行内容awk '{print $0}' file
    $n第n个字段(n=1,2,3...)awk '{print $3}' file
    NR当前行号(记录号)awk '{print NR, $0}' file
    NF当前行的字段数量awk '{print NF}' file
    FS输入字段分隔符(默认空格)awk 'BEGIN{FS=":"}...'
    OFS输出字段分隔符(默认空格)awk 'BEGIN{OFS="-"}{print $1,$2}'
    FILENAME当前处理文件名awk '{print FILENAME}' file
  • ​常用选项​​:

    选项作用示例
    -F设置字段分隔符awk -F',' '{print $2}' data.csv
    -v定义awk变量awk -v name="Alice" '/name/ {print name}'
  • ​特殊模式​​:

    模式作用
    BEGIN处理文本前执行的动作
    END处理完所有文本后执行的动作

​2. 示例​

假设存在名为 employees.txt 的文件,内容为:

Alice Johnson|28|Engineer|55000
Bob Smith|32|Manager|72000
Carol Davis|25|Designer|48000

​基础操作​​:

# 1. 打印整行
awk '{print $0}' employees.txt# 2. 打印第一列(默认空格分隔,效果不佳)
awk '{print $1}' employees.txt# 3. 设置分隔符为"|",打印姓名
awk -F'|' '{print $1}' employees.txt
# 输出:
# Alice Johnson
# Bob Smith
# Carol Davis# 4. 打印行号和第3列
awk -F'|' '{print NR, $3}' employees.txt
# 输出:
# 1 Engineer
# 2 Manager
# 3 Designer# 5. 打印最后一行(END模式)
awk -F'|' 'END{print "Last employee:", $1}' employees.txt
# 输出:Last employee: Carol Davis

​条件过滤​​:

# 1. 筛选年龄>30的员工
awk -F'|' '$2 > 30 {print $1}' employees.txt
# 输出:Bob Smith# 2. 筛选工程师
awk -F'|' '$3 == "Engineer" {print $1, "($4)"}' employees.txt
# 输出:Alice Johnson (55000)# 3. 使用正则:匹配姓氏含"S"的员工
awk -F'|' '$1 ~ /S/ {print $1}' employees.txt
# 输出:Bob Smith

​计算与统计​​:

# 1. 计算平均工资
awk -F'|' 'NR>1 {sum+=$4; count++} END{print "Avg Salary:", sum/count}' employees.txt
# 输出:Avg Salary: 58333.3# 2. 格式化输出(设置OFS)
awk -F'|' 'BEGIN{OFS=" | "} {print NR, $1, "Salary: $" $4}' employees.txt
# 输出:
# 1 | Alice Johnson | Salary: $55000
# 2 | Bob Smith | Salary: $72000
# 3 | Carol Davis | Salary: $48000# 3. 统计岗位数量(使用数组)
awk -F'|' 'NR>1 {jobs[$3]++} END{for(j in jobs) print j, jobs[j] " person(s)"}' employees.txt
# 输出:
# Engineer 1 person(s)
# Manager 1 person(s)
# Designer 1 person(s)

​BEGIN块初始化​​:

# 添加表头行和美元符号
awk -F'|' 'BEGIN {print "ID | Name | Position | Salary\n--------------------------"} NR>1 {print NR-1, $1, $3, "$" $4}' employees.txt
# 输出:
# ID | Name | Position | Salary
# --------------------------
# 1 Alice Johnson Engineer $55000
# 2 Bob Smith Manager $72000
# 3 Carol Davis Designer $48000

​3. 高级技巧​

  1. ​内置函数​​:
    # 转换小写
    echo "HELLO" | awk '{print tolower($0)}'  # → hello# 字符串截取
    awk -F'|' '{print substr($1, 1, 3)}' employees.txt  # → Ali, Bob, Car
  2. ​条件语句​​:
    # 工资分级
    awk -F'|' '{if ($4 > 60000) status="High"else if ($4 > 50000) status="Medium"else status="Low"print $1, ":", status
    }' employees.txt
  3. ​多文件处理​​:
    # 同时处理两个文件(行号重置)
    awk '{print FILENAME, NR, "->", $0}' file1.txt file2.txt
  4. ​处理复杂日志​​:
    # 统计Nginx日志中每个IP的访问量
    awk '{ip_count[$1]++} END{for(i in ip_count) print i, ip_count[i]}' access.log

​4. 常见应用场景​

场景awk命令
提取CSV列awk -F',' '{print $2,$5}' data.csv
分析日志awk '/ERROR/ {print $1,$5}' app.log
文本统计awk '{chars+=length($0);words+=NF} END{print "Chars:",chars,"Words:",words}'
数据转换awk 'BEGIN{OFS=":"} {$1=$1; print}' file (重新格式化分隔符)
关联多个文件awk 'NR==FNR{a[$1]=$2;next} {print $0, a[$1]}' file1 file2

✅ ​​最佳实践​​:

  • 处理结构化数据优先使用awk而非grep/sed
  • 复杂任务用BEGIN预处理和END汇总
  • 避免修改源文件,输出到新文件:awk '...' input > output

⚠️ ​​注意​​:

  1. $0$1等变量不用$前缀(print $1正确,print {$1}错误)
  2. 数值计算需确保字段是数字(非数字会当作0)

 四、关于grep与find命令的区别

简单来讲,find主要查找文件,而grep主要查找文件内容

特性​grepfind
​目标​文件​​内容​文件/目录​​自身属性​
​主要功能​文本模式匹配按条件查找文件/目录
​递归搜索​需 -r 选项(如 grep -r天生递归(从指定目录开始)
​结合正则​默认支持正则表达式仅 -name 支持基础通配符(需用 -regex 支持完整正则)

find(文件查找工具)​

  • ​用途​​:在​​目录树​​中查找符合条件(名称、大小、时间等)的​​文件/目录​​。
  • ​工作对象​​:文件/目录的元数据(如文件名、大小、修改时间)。
  • ​常用选项​​:
    • -name:按文件名搜索(如 find . -name "*.jpg")。
    • -type:按类型搜索(f=文件,d=目录)。
    • -size:按文件大小搜索(如 find / -size +100M 找大于100MB的文件)。
    • -mtime:按修改时间搜索(如 find ~ -mtime -7 找7天内修改的文件)。
    • -exec:对搜索结果执行命令(如 find . -name "*.tmp" -exec rm {} \;)。
  • ​示例​​:
    # 查找 /home 下所有 .txt 文件
    find /home -type f -name "*.txt"# 删除 /tmp 中 30 天前修改的 .log 文件
    find /tmp -name "*.log" -mtime +30 -delete

    所以在实际使用时,一般先使用find查找到文件,然后使用grep对文件内容进行操作。

 

http://www.dtcms.com/a/266642.html

相关文章:

  • RT‑DETR 系列发展时间顺序
  • 判断文件是否有硬链接
  • PyTorch实战(14)——条件生成对抗网络(conditional GAN,cGAN)
  • 基于PHP+MySQL实现(Web)英语学习与测试平台
  • 【Git】git命令合集
  • vue 常用搭配使用工具
  • 影楼精修-智能修图Agent
  • 2025.06.27-14.44 C语言开发:Onvif(二)
  • 批量PDF转换工具,一键转换Word Excel
  • Spring Boot多环境开发-Profiles
  • [netty5: HttpObject]-源码解析
  • OpenShift AI - 使用 NVIDIA Triton Runtime 运行模型
  • ubuntu 20.04.6 sudo 源码包在线升级到1.9.17p1
  • 跨境电商ERP怎么选?有没有适合新手起步免费版的ERP系统?
  • Zabbix Web检测报错“Could not resolve host: blog.cn; Unknown error”
  • ABP VNext + RediSearch:微服务级全文检索
  • Java项目:基于SSM框架实现的在线投稿管理系统【ssm+B/S架构+源码+数据库+毕业论文】
  • 供应链管理:指标评估方式分类与详解
  • JVM 简介与作用
  • Unity HDRP + Azure IoT 的 Python 后端实现与集成方案
  • git教程-pycharm使用tag打标签
  • 云渲染时,电脑能关机吗?关键阶段操作指南
  • Android课程前言
  • Vue-19-前端框架Vue之应用基础组件通信(二)
  • Linux基本命令篇 —— uname命令
  • HarmonyOS学习记录3
  • 【技术架构解析】国产化双复旦微FPGA+飞腾D2000核心板架构
  • 「源力觉醒 创作者计划」_文心 4.5 开源模型玩出花——教育场景下 Scratch 积木自动化生成的部署实践与优化
  • 【算法刷题记录001】整型数组合并(java代码实现)
  • 转Go学习笔记