Linux文本处理工具与正则表达式实战指南
本文基于Ubuntu 24.04 LTS系统,在真实服务器上执行所有命令并捕获输出。涵盖VIM编辑器、文本处理三剑客(grep/sed/awk)、常用文本工具、正则表达式、文件查找与压缩打包等核心技能。
系统环境:Ubuntu 24.04.4 LTS (Noble Numbat) | VIM 9.1
📑 章节导航
- 一、VIM编辑器三种模式
- 二、文本处理工具
- 三、grep与正则表达式
- 四、sed流编辑器
- 五、find文件查找
- 六、压缩与打包
- 七、其他实用文本工具
- 八、总结
一、VIM编辑器三种模式
VIM(Vi IMproved)是Linux下最强大的文本编辑器之一。先来看看服务器上的版本信息:
$vim--version|head-5VIM - Vi IMproved9.1(2024Jan 02, compiled Jul13202617:17:48)Included patches:1-16,647,678,697Modified by team+vim@tracker.debian.org Compiled by team+vim@tracker.debian.org Huge version without GUI. Features included(+)or not(-):1.1 三种模式详解
VIM有三种核心工作模式,理解它们的切换是高效编辑的基础:
| 模式 | 说明 | 进入方式 |
|---|---|---|
| 命令模式(Normal) | 默认模式,用于光标移动、复制粘贴、删除等 | 按Esc键 |
| 插入模式(Insert) | 文本输入模式,像普通编辑器一样打字 | 命令模式下按i/a/o等 |
| 底线命令模式(Ex) | 执行保存、退出、替换等命令 | 命令模式下按:进入 |
1.2 模式切换图解
┌─────────────┐ i/a/o ┌─────────────┐ │ 命令模式 │ ──────────→ │ 插入模式 │ │ (Normal) │ ←────────── │ (Insert) │ └─────────────┘ Esc └─────────────┘ │ │ : (冒号) ↓ ┌─────────────┐ │ 底线命令模式 │ │ (Ex) │ └─────────────┘1.3 常用命令速查
命令模式下的光标移动:
h/j/k/l— 左/下/上/右移动gg— 跳到文件首行G— 跳到文件末行0— 跳到行首$— 跳到行尾w/b— 向前/向后跳一个单词
命令模式下的编辑操作:
dd— 删除(剪切)当前行yy— 复制当前行p— 粘贴u— 撤销Ctrl+r— 恢复x— 删除光标处字符
底线命令模式:
:w— 保存:q— 退出:wq— 保存并退出:q!— 强制退出不保存:%s/old/new/g— 全局替换
💡实战技巧:在命令模式下输入
:set nu可以显示行号,:set paste可以在粘贴时避免自动缩进问题,这在从外部复制配置到VIM时非常实用。
二、文本处理工具
Linux提供了丰富的文本处理工具,它们是运维人员的"瑞士军刀"。我们先创建一个演示文件:
$cat>/tmp/demo.txt<<"EOF" apple 10 3.5 banana 20 2.8 apple 15 4.2 cherry 8 5.0 banana 12 3.8 date 5 6.0 apple 20 3.5 elderberry 3 8.5 cherry 10 5.0 fig 7 4.5 EOF2.1 cut — 按列提取
cut命令按分隔符提取指定列,在处理CSV或空格分隔的数据时非常方便:
$cut-d" "-f1/tmp/demo.txt apple banana apple cherry bananadateapple elderberry cherry fig $cut-d" "-f1-2 /tmp/demo.txt apple10banana20apple15cherry8banana12date5apple20elderberry3cherry10fig7-d" "指定空格为分隔符-f1提取第1列,-f1-2提取第1到2列
2.2 sort — 排序
sort支持字典序和数值排序,还能指定分隔符和排序字段:
$sort/tmp/demo.txt apple103.5apple154.2apple203.5banana123.8banana202.8cherry105.0cherry85.0date56.0elderberry38.5fig74.5$sort-t" "-k2-rn/tmp/demo.txt banana202.8apple203.5apple154.2banana123.8cherry105.0apple103.5cherry85.0fig74.5date56.0elderberry38.5-t" "指定分隔符为空格-k2按第2列排序-rn逆序数值排序(r=reverse, n=numeric)
2.3 uniq — 去重与统计
uniq只能去除连续的重复行,所以通常配合sort使用:
$cut-d" "-f1/tmp/demo.txt|sort|uniqapple banana cherrydateelderberry fig $cut-d" "-f1/tmp/demo.txt|sort|uniq-c3apple2banana2cherry1date1elderberry1figuniq -c统计每行出现的次数,这在日志分析中极为常用——比如统计各种HTTP状态码的出现频率。
2.4 tr — 字符转换
tr用于字符级别的替换、删除和压缩:
$echo"hello world"|tr"a-z""A-Z"HELLO WORLD $echo"abc123def456"|tr-d"0-9"abcdef $echo"aaabbbccc"|tr-s"abc"abctr "a-z" "A-Z"— 小写转大写tr -d "0-9"— 删除所有数字tr -s "abc"— 压缩连续重复的a、b、c字符
💡实战技巧:
tr经常用于处理Windows换行符(CRLF→LF):cat file.txt | tr -d '\r' > file_unix.txt
三、grep与正则表达式
grep是Linux下最常用的文本搜索工具,配合正则表达式可以实现强大的模式匹配。
3.1 grep基本用法
$grep"apple"/tmp/demo.txt apple103.5apple154.2apple203.5$grep-i"apple"<<<$'Apple\napple\nAPPLE\nbanana'Apple apple APPLE $grep-v"apple"/tmp/demo.txt banana202.8cherry85.0banana123.8date56.0elderberry38.5cherry105.0fig74.5$grep-n"banana"/tmp/demo.txt2:banana202.85:banana123.8$grep-c"apple"/tmp/demo.txt3| 选项 | 功能 |
|---|---|
-i | 忽略大小写 |
-v | 反向匹配(输出不匹配的行) |
-n | 显示行号 |
-c | 只输出匹配行数 |
-r | 递归搜索目录 |
-E | 使用扩展正则表达式 |
-o | 只输出匹配的部分 |
3.2 基础正则表达式(BRE)
$grep"^a"/tmp/demo.txt apple103.5apple154.2apple203.5$grep"0$"/tmp/demo.txt cherry85.0date56.0cherry105.0$grep"[ab]"/tmp/demo.txt apple103.5banana202.8apple154.2banana123.8date56.0apple203.5elderberry38.5基础正则元字符:
^— 行首锚定$— 行尾锚定[abc]— 匹配a或b或c[^abc]— 匹配非a、b、c的字符.— 匹配任意单个字符*— 前一个字符出现0次或多次
3.3 扩展正则表达式(ERE)
使用grep -E或egrep启用扩展正则,支持更多元字符:
$grep-E"apple|banana"/tmp/demo.txt apple103.5banana202.8apple154.2banana123.8apple203.5$grep-E"^(a|b)"/tmp/demo.txt apple103.5banana202.8apple154.2banana123.8apple203.5$grep-E"[0-9]{2,}"/tmp/demo.txt apple103.5banana202.8apple154.2banana123.8apple203.5cherry105.0扩展正则新增元字符:
|— 或(alternation)+— 前一个字符出现1次或多次?— 前一个字符出现0次或1次{n,m}— 前一个字符出现n到m次()— 分组
💡实战技巧:排查日志中的IP地址可以用
grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" access.log;查找邮箱可以用grep -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" file.txt
四、sed流编辑器
sed(Stream Editor)是强大的文本流编辑器,擅长对文本进行批量替换、删除、插入等操作。
4.1 替换操作
$echo"hello world"|sed"s/world/Linux/"hello Linux $echo"apple apple apple"|sed"s/apple/fruit/g"fruit fruit fruit $sed"s/apple/Apple/"/tmp/demo.txt|head-5Apple103.5banana202.8Apple154.2cherry85.0banana123.8s/old/new/— 替换每行第一个匹配s/old/new/g— 全局替换(替换所有匹配)s/old/new/gi— 全局替换且忽略大小写
4.2 删除操作
$sed"/banana/d"/tmp/demo.txt apple103.5apple154.2cherry85.0date56.0apple203.5elderberry38.5cherry105.0fig74.5/banana/d删除所有包含"banana"的行。
4.3 插入与追加
$echo-e"line1\nline2\nline3"|sed"2i\INSERTED LINE"line1 INSERTED LINE line2 line3 $echo-e"line1\nline2\nline3"|sed"2a\APPENDED LINE"line1 line2 APPENDED LINE line32i\TEXT— 在第2行前插入2a\TEXT— 在第2行后追加
4.4 多命令执行与打印
$echo"hello world"|sed-e"s/hello/HELLO/"-e"s/world/WORLD/"HELLO WORLD $sed-n"/apple/p"/tmp/demo.txt apple103.5apple154.2apple203.5-e执行多条sed命令-n配合p只打印匹配行(类似grep)
💡实战技巧:批量修改配置文件时,用
sed -i.bak 's/old/new/g' config.conf,-i.bak会先备份原文件再修改,安全可回退。
五、find文件查找
find是Linux下最强大的文件查找工具,支持按名称、类型、大小、时间、权限等多种条件查找。
5.1 按名称和类型查找
$find/tmp-name"*.txt"-typef2>/dev/null|head-10/tmp/compress_test2.txt /tmp/demo.txt /tmp/error.txt /tmp/test_moved.txt /tmp/redirect_test.txt5.2 按时间查找
$find/etc-mtime-1-typef2>/dev/null|head-10/etc/shadow- /etc/passwd /etc/gshadow /etc/subuid /etc/subgid- /etc/init.d/uniagentd /etc/shadow /etc/subgid /etc/group /etc/hosts-mtime -1表示最近1天内修改的文件。-mtime +7表示7天前修改的文件。
5.3 按大小查找
$find/var/log-size+1M-typef2>/dev/null|head-10/var/log/journal/615dfb09d1ba43a2bddb9e54eb187456/system@5341ec7f25ac4b7e81c7b44956b7603d-00000000000009c7-0006571bba886682.journal /var/log/journal/615dfb09d1ba43a2bddb9e54eb187456/system.journal5.4 按权限和用户查找
$find/etc-perm644-name"*.conf"-typef2>/dev/null|head-5/etc/apport/crashdb.conf /etc/host.conf /etc/apparmor/parser.conf /etc/overlayroot.conf /etc/dbus-1/system.d/com.ubuntu.SoftwareProperties.conf $find/tmp-userroot-name"*.txt"-typef2>/dev/null|head-5/tmp/compress_test2.txt /tmp/demo.txt /tmp/error.txt /tmp/test_moved.txt /tmp/redirect_test.txt5.5 执行动作与多条件组合
$find/tmp-name"demo.txt"-execwc-l{}\;10/tmp/demo.txt $find/etc-name"*.conf"-size+1k-typef2>/dev/null|head-5/etc/apport/crashdb.conf /etc/apparmor/parser.conf /etc/overlayroot.conf /etc/initramfs-tools/initramfs.conf /etc/selinux/semanage.conf-exec CMD {} \;— 对找到的每个文件执行命令- 多个条件默认是AND关系,用
-o连接表示OR
💡实战技巧:批量清理7天前的日志:
find /var/log -name "*.log" -mtime +7 -exec rm -f {} \;。建议先用
六、压缩与打包
Linux下常用的压缩工具有gzip、bzip2,打包工具主要是tar。
6.1 gzip 压缩解压
$ls-lh/tmp/compress_test.txt -rw-r--r--1root root71Oct1622:56 /tmp/compress_test.txt $gzip/tmp/compress_test.txt $ls-lh/tmp/compress_test.txt.gz -rw-r--r--1root root107Oct1622:56 /tmp/compress_test.txt.gz $ gunzip /tmp/compress_test.txt.gz $ls-lh/tmp/compress_test.txt -rw-r--r--1root root71Oct1622:56 /tmp/compress_test.txt注:对于很小的文件,gzip压缩后可能反而变大(因为gzip头部开销),这在实际中是正常现象。
6.2 tar 打包压缩
tar是最常用的打包工具,配合不同压缩选项实现不同压缩率:
# 打包(不压缩)$tar-cvf/tmp/archive.tar /tmp/compress_test.txt /tmp/compress_test2.txt $ls-lh/tmp/archive.tar -rw-r--r--1root root 10K Oct1622:56 /tmp/archive.tar# 打包 + gzip压缩$tar-czvf/tmp/archive.tar.gz /tmp/compress_test.txt /tmp/compress_test2.txt $ls-lh/tmp/archive.tar.gz -rw-r--r--1root root207Oct1622:56 /tmp/archive.tar.gz# 打包 + bzip2压缩$tar-cjvf/tmp/archive.tar.bz2 /tmp/compress_test.txt /tmp/compress_test2.txt $ls-lh/tmp/archive.tar.bz2 -rw-r--r--1root root232Oct1622:56 /tmp/archive.tar.bz2| 选项 | 说明 |
|---|---|
-c | 创建新包(create) |
-x | 解包(extract) |
-v | 显示详细过程(verbose) |
-f | 指定文件名 |
-z | 使用gzip压缩/解压 |
-j | 使用bzip2压缩/解压 |
-t | 查看包内容 |
6.3 查看与解压
# 查看包内容(不解压)$tar-tzvf/tmp/archive.tar.gz -rw-r--r-- root/root712026-10-1622:56 tmp/compress_test.txt -rw-r--r-- root/root712026-10-1622:56 tmp/compress_test2.txt# 解压到指定目录$mkdir-p/tmp/extract_test $tar-xzvf/tmp/archive.tar.gz-C/tmp/extract_test tmp/compress_test.txt tmp/compress_test2.txt $ls-l/tmp/extract_test/tmp/ total8-rw-r--r--1root root71Oct1622:56 compress_test2.txt -rw-r--r--1root root71Oct1622:56 compress_test.txt💡实战技巧:备份网站时常用
tar -czvf backup_$(date +%Y%m%d).tar.gz /var/www/html/,结合日期命名方便管理多个备份版本。
七、其他实用文本工具
7.1 wc — 统计行数/单词数/字节数
$wc/tmp/demo.txt1030132/tmp/demo.txt分别表示10行、30个单词、132个字节。
7.2 head/tail — 查看文件头尾
$head-3/tmp/demo.txt apple103.5banana202.8apple154.2$tail-3/tmp/demo.txt elderberry38.5cherry105.0fig74.5tail -f实时追踪文件变化,是查看日志的利器。
7.3 diff — 文件比较
$diff/tmp/file_a.txt /tmp/file_b.txt 2c2<line2 --->line2_modified2c2表示第2行有变化(c=change),<是左边文件,>是右边文件。
7.4 paste — 合并文件
$paste/tmp/p1.txt /tmp/p2.txt a1b2c37.5 tee — 双向输出
$echo"tee test"|tee/tmp/tee_test.txtteetesttee既在屏幕上显示输出,又写入文件,常用于管道中保存中间结果。
7.6 xargs — 管道传参
$echo-e"/tmp/demo.txt\n/tmp/file_a.txt"|xargswc-l10/tmp/demo.txt3/tmp/file_a.txt13totalxargs将前一个命令的输出作为后一个命令的参数,解决部分命令不支持管道输入的问题。
八、总结
本文在Ubuntu 24.04 LTS真实服务器上实操演示了Linux文本处理的核心工具链:
| 工具 | 核心功能 | 典型场景 |
|---|---|---|
| VIM | 文本编辑 | 配置文件编辑、脚本编写 |
| cut | 按列提取 | 处理CSV、提取特定字段 |
| sort | 排序 | 日志排序、数据整理 |
| uniq | 去重统计 | 频次统计、数据去重 |
| tr | 字符转换 | 大小写转换、字符删除 |
| grep | 模式匹配 | 日志搜索、配置查找 |
| sed | 流编辑 | 批量替换、文本修改 |
| find | 文件查找 | 清理旧文件、定位配置 |
| tar | 打包压缩 | 备份归档、文件传输 |
核心要点:
- VIM三模式切换是高效编辑的基础,
Esc回命令模式是肌肉记忆 grep + 正则表达式是文本搜索的黄金组合,基础正则与扩展正则的区别在于元字符支持范围sed的-i选项可以直接修改文件,配合.bak后缀可安全回退find的-exec可以对查找结果批量执行命令,是自动化运维的利器tar -czvf是最常用的打包压缩组合,兼顾速度和压缩率
掌握这些工具,你已经具备了处理Linux下绝大多数文本处理任务的能力。下一章我们将进入Shell脚本编程的世界,把这些工具组合成自动化方案。