菜鸟科技网

Linux截取命令有哪些常用方法?

核心概念:正则表达式

在介绍具体命令前,必须了解正则表达式,它是这些命令进行模式匹配的“语法”。

Linux截取命令有哪些常用方法?-图1
(图片来源网络,侵删)
元字符 功能 示例
匹配任意单个字符 gr.p 匹配 gr + 任意字符 + p,如 grep, gr5p
匹配前一个字符零次或多次 a*b 匹配 b, ab, aaaab
^ 匹配行首 ^hello 匹配以 hello 开头的行
匹配行尾 world$ 匹配以 world 结尾的行
[] 匹配指定范围内的一个字符 [0-9] 匹配任意一个数字
[a-z] 匹配任意一个小写字母 [A-Z] 匹配任意一个大写字母
[^] 匹配指定范围外的任意一个字符 [^0-9] 匹配任意一个非数字字符
\ 转义元字符,匹配其本身 匹配 这个字符,而不是任意字符
或,匹配 两边的任意一个表达式 cat\|dog 匹配 catdog
分组,将括号内的内容作为一个整体 (ab)+ 匹配 ab, abab, ababab

三大截取/处理命令详解

grep (Global Regular Expression Print)

核心定位: 按行过滤,根据指定的“模式”(正则表达式)搜索文本,并打印出匹配的整行

常用选项:

  • -i: 忽略大小写。
  • -v: 反向选择,即打印不匹配的行。
  • -n: 显示匹配行的行号。
  • -c: 只输出匹配行的总数。
  • -E: 使用扩展正则表达式 (ERE),支持 , , , 等元字符。
  • -w: 匹配整个单词。
  • -o: 只输出匹配到的部分,而不是整行。

基本用法:

# 基本过滤,查找包含 "error" 的行
grep "error" logfile.txt
# 忽略大小写查找 "Warning"
grep -i "warning" logfile.txt
# 查找不包含 "info" 的行
grep -v "info" logfile.txt
# 显示匹配行的行号
grep -n "error" logfile.txt
# 只输出匹配到的内容本身
echo "This is a test. The test is simple." | grep -o "test"
# 输出:
# test
# test

sed (Stream Editor)

核心定位: 按行处理和编辑sed 是一个流编辑器,它一次处理一行,可以将结果输出到标准输出(通常是屏幕),也可以保存到文件,它不仅能截取,还能进行强大的增、删、改操作。

截取相关命令:

Linux截取命令有哪些常用方法?-图2
(图片来源网络,侵删)
  • p: 打印 (print),通常与 -n 选项配合使用,-n 会取消默认的输出,只打印你指定的行。
  • d: 删除 (delete)。
  • s/.../.../g: 替换 (substitute)。

基本用法:

# 打印第 3 行
sed -n '3p' logfile.txt
# 打印第 3 到第 5 行
sed -n '3,5p' logfile.txt
# 打印从第 10 行开始的所有行
sed -n '10,$p' logfile.txt
# 打印所有包含 "error" 的行
# /pattern/p 是 sed 的语法,表示匹配 pattern 的行执行 p 命令
sed -n '/error/p' logfile.txt
# 删除第 3 行到第 5 行,并输出结果(原文件不变)
sed '3,5d' logfile.txt
# 替换所有 "error" 为 "ERROR"
# g 表示全局替换,否则每行只替换第一个匹配项
sed 's/error/ERROR/g' logfile.txt
# 将修改结果保存到新文件(使用 -i 会直接修改原文件,请谨慎!)
sed 's/error/ERROR/g' logfile.txt > new_logfile.txt

awk

核心定位: 按字段处理awk 是最强大的文本处理工具,它将每一行按指定的分隔符(默认是空格或制表符)切分成“字段”,然后可以对每个字段进行复杂的操作。awk 本身是一门完整的脚本语言。

基本语法: awk 'BEGIN { ... } pattern { action } END { ... }' file

  • BEGIN: 在处理所有行之前执行一次,通常用于初始化变量。
  • pattern { action }: 对匹配 pattern 的行执行 action,如果省略 pattern,则对所有行执行 action
  • END: 在处理完所有行之后执行一次,通常用于输出最终结果。

常用变量:

Linux截取命令有哪些常用方法?-图3
(图片来源网络,侵删)
  • $0: 当前行。
  • $1, $2, ...: 第一个、第二个...字段。
  • NF: 当前行的字段数量 (Number of Fields)。
  • NR: 当前行号 (Number of Record/Row)。
  • FS: 字段分隔符 (Field Separator),默认是空格。
  • OFS: 输出字段分隔符 (Output Field Separator),默认是空格。

基本用法:

# 打印第 1 个字段(第一列)
# 默认以空格或制表符分隔
awk '{print $1}' logfile.txt
# 打印第 1 个和第 3 个字段,并用逗号分隔
awk '{print $1 "," $3}' logfile.txt
# 打印字段数大于 4 的行
awk 'NF > 4' logfile.txt
# 打印行号和内容
awk '{print NR ": " $0}' logfile.txt
# 指定分隔符为冒号,打印 /etc/passwd 文件的第一列(用户名)和最后一列(解释)
awk -F ':' '{print $1, $NF}' /etc/passwd
# 统计包含 "error" 的行数
awk '/error/{count++} END {print "Error count:", count}' logfile.txt

命令对比与选择

功能 grep sed awk
核心用途 按行过滤,快速查找包含特定模式的行 按行编辑,增、删、改、查行 按字段处理,对列进行复杂操作
输出单位 整行或匹配部分(-o 整行或修改后的行 字段或自定义格式化输出
复杂度 简单,适合快速过滤 中等,适合简单编辑和替换 强大,适合复杂计算和报告生成
典型场景 ps aux | grep "nginx"
tail -f log | grep "error"
sed 's/old/new/g' file
sed -n '10,20p' file
awk '{sum+=$1} END {print sum}'
awk -F ':' '{print $1}' /etc/passwd

如何选择?

  1. 只想快速找出包含某些词的行?

    • grep,这是最直接、最高效的方式。
  2. 需要删除、提取特定的行(如第 5-10 行)?

    • sedsed -n '5,10p' 是提取行的标准操作。
  3. 需要提取或处理某一列(如 IP 地址、用户名)?

    • awkawk '{print $1}' 是提取列的标准操作。
  4. 需要同时满足行和列的条件?

    • 组合使用!先用 grep 过滤出行,再用 awk 处理列。
      # 从日志中找出所有 "error" 行,并打印它们的第 5 个字段
      grep "error" logfile.txt | awk '{print $5}'

实战案例

假设我们有以下文件 data.txt

Name, Age, City
Alice, 30, New York
Bob, 25, London
Charlie, 35, Paris
David, 28, New York

任务 1:找出所有年龄大于 28 的人的姓名和城市。

  • 分析: 需要按行过滤(grep),然后按字段提取(awk)。
  • 命令:
    # 先过滤出年龄大于 28 的行,然后提取第 1 和第 3 列
    grep -E '[0-9]{2,}' data.txt | awk -F ',' '{if ($2 > 28) print $1, $3}'
    • grep -E '[0-9]{2,}':匹配包含至少两位数字的行(即年龄行)。
    • awk -F ',':设置字段分隔符为逗号。
    • if ($2 > 28) print $1, $3:如果第二个字段(年龄)大于 28,则打印第一个和第三个字段。

任务 2:统计每个城市有多少人。

  • 分析: 需要按列分组并计数,这是 awk 的强项。
  • 命令:
    awk -F ',' '!/^Name/ {city[$3]++} END {for (c in city) print c, city[c]}' data.txt
    • !/^Name/:跳过以 "Name" 开头的行(标题行)。
    • city[$3]++:使用数组 city,以城市名($3)为键,出现次数为值,进行累加。
    • END {for (c in city) print c, city[c]}:处理完所有行后,遍历 city 数组并输出结果。

任务 3:提取所有 "New York" 城市的人的姓名。

  • 分析: 需要按行过滤(grep),然后按字段提取(awk)。
  • 命令:
    grep "New York" data.txt | awk -F ',' '{print $1}'
    • grep "New York":找出包含 "New York" 的行。
    • awk -F ',' '{print $1}':以逗号为分隔符,打印第一个字段(姓名)。

希望这份详细的指南能帮助你熟练掌握 Linux 的截取命令!

分享:
扫描分享到社交APP
上一篇
下一篇