【文本处理】正则表达式与grep/sed/awk

正则表达式

常用的正则表达式元字符及其含义:

1. 字符匹配:

  • . : 匹配任意单个字符(除了换行符)
  • [ ] : 匹配括号内的任意一个字符
  • [^ ] : 匹配不在括号内的任意一个字符
  • \char : 转义字符,使char失去特殊含义

2. 预定义字符类:

  • \d : 匹配一个数字,等同于[0-9](注意:在BRE中可能不支持,通常使用[0-9])
  • \D : 匹配非数字,等同于[^0-9]
  • \w : 匹配字母、数字、下划线,等同于[A-Za-z0-9_]
  • \W : 匹配非字母、数字、下划线
  • \s : 匹配空白字符(空格、制表符、换行符等)
  • \S : 匹配非空白字符

3. 数量词:

  • * : 匹配前面的子表达式零次或多次,例如a* 匹配 “”, “a”, “aa”, …
  • + : 匹配前面的子表达式一次或多次,a+ 匹配 “a”, “aa”, …
  • ? : 匹配前面的子表达式零次或一次,a? 匹配 “”, “a”
  • {n} : 匹配确定的n次,a{3} 匹配 “aaa”
  • {n,} : 匹配至少n次,a{2,} 匹配 “aa”, “aaa”, …
  • {n,m} : 匹配至少n次,最多m次, a{2,4} 匹配 “aa”, “aaa”, “aaaa”

4. 位置锚定:

  • ^ : 匹配字符串的开始
  • $ : 匹配字符串的结束
  • \< : 匹配单词的开始
  • \> : 匹配单词的结束

5. 分组与捕获:

  • ( ) : 将括号内的内容作为一个分组,并捕获匹配的文本(在BRE中需要转义为\( \)
  • (?: ) : 非捕获分组,不捕获匹配的文本(在ERE中可用)

6. 或操作:

  • | : 匹配左右任意一个表达式(在BRE中需要转义为\|

grep

基本语法:

grep [选项] 模式 [文件...]

常用选项:

-i:不区分大小写
# 搜索 hello,不区分大小写
grep -i "hello" file.txt

# 实际应用:搜索日志中的错误信息
grep -i "error\|warning\|critical" /var/log/syslog

# 搜索配置文件中的设置(忽略大小写)
grep -i "server_name" nginx.conf
-v:反向过滤
# 排除包含注释的行
grep -v "^#" config.conf

# 排除空行
grep -v "^$" file.txt

# 排除注释和空行
grep -v "^#\|^$" config.conf

# 实际应用:查看非本地IP的连接
netstat -an | grep "ESTABLISHED" | grep -v "127.0.0.1"
-o:只输出匹配的关键字
# 只提取IP地址
grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" access.log

# 只提取邮箱地址
grep -oE "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b" users.txt

# 实际应用:统计关键词出现次数
grep -o "error" app.log | wc -l
-E:使用扩展正则表达式
# 基本正则表达式(需要转义)
grep "go\{2,\}d" file.txt    # 匹配 good, goood, gooood 等

# 扩展正则表达式(不需要转义)
grep -E "go{2,}d" file.txt

# 或者使用 egrep(等价于 grep -E)
egrep "go{2,}d" file.txt

# 实际应用:匹配多种模式
grep -E "error|warning|critical" system.log
-c:统计匹配行数
# 统计包含error的行数
grep -c "error" app.log

# 统计不同用户登录次数
grep -c "user1" auth.log
grep -c "user2" auth.log

# 实际应用:监控错误频率
error_count=$(grep -c "ERROR" /var/log/app.log)
echo "错误数量: $error_count"

awk

​ awk是一种文本处理工具,非常适合处理结构化数据(如CSV、日志等)。它逐行处理文本,并可以对每行进行分割成字段(列)然后处理。

基本格式

awk [-F"分隔符"] '模式 {动作}' 文件名

① awk 文本列处理

基本列操作

# 打印指定列
awk '{print $1}' test.txt           # 打印第一列(姓名)
awk '{print $1, $3}' test.txt       # 打印第一列和第三列
awk '{print $NF}' test.txt          # 打印最后一列(NF=字段数量)
awk '{print $(NF-1)}' test.txt      # 打印倒数第二列

② -F 分隔符详解

不同分隔符的使用

# 逗号分隔
awk -F"," '{print $1, $3}' data.csv

# 冒号分隔  
awk -F":" '{print $2}' config.conf

# 多个分隔符
awk -F"[,:]" '{print $1, $3}' data.csv

# 默认空格分隔(可以省略 -F" ")
awk '{print $1, $2}' test.txt

③ 位置参数和输出控制

位置参数操作

# 基本位置参数
awk '{print $1}' test.txt              # 第一列
awk '{print $2, $4}' test.txt          # 第二和第四列
awk '{print $0}' test.txt              # 整行内容

# 列运算和拼接
awk '{print "姓名:" $1, "薪资:" $4}' test.txt
awk '{print $1 "-" $3, "工资:" $4*1.1}' test.txt
awk '{print toupper($1), tolower($3)}' test.txt

格式化输出

# 使用printf格式化
awk '{printf "%-10s %-8s %-10s %-8s\n", $1, $2, $3, $4}' test.txt

# 表头+数据
awk 'BEGIN{printf "%-10s %-8s %-10s %-8s\n", "姓名", "年龄", "职业", "工资"} {printf "%-10s %-8s %-10s %-8s\n", $1, $2, $3, $4}' test.txt

④ NR 行号控制

行范围选择

# 从第2行开始处理
awk 'NR>=2{print $1, $3}' test.txt

# 处理特定行范围 (2-3行)
awk 'NR>=2 && NR<=3{print NR ":", $0}' test.txt

# 跳过第一行(表头)
awk 'NR>1{print $0}' test.txt

# 只处理奇数行
awk 'NR%2==1{print NR, $0}' test.txt

# 只处理偶数行  
awk 'NR%2==0{print NR, $0}' test.txt

sed

sed(Stream Editor)是一个强大的文本处理工具,用于对文本进行过滤和转换。它按行处理文本,支持正则表达式。

基本语法

bash

sed [选项] '命令' 输入文件

常用选项

  • -n:禁止默认输出,只有经过sed处理的行才会被输出
  • -e:允许执行多个脚本
  • -f:从文件中读取sed脚本
  • -i:直接修改文件内容(小心使用)
  • -r:使用扩展正则表达式

基本命令

  • s:替换
  • d:删除
  • p:打印
  • a:追加
  • i:插入
  • c:替换行

示例

替换操作
# 将每行第一个出现的old替换为new
sed 's/old/new/' file.txt

# 全局替换(每行所有出现的old替换为new)
sed 's/old/new/g' file.txt

# 替换第N次出现的匹配
sed 's/old/new/2' file.txt        # 替换第二次出现
sed 's/old/new/2g' file.txt       # 从第二次开始替换所有

# 使用其他分隔符,例如替换路径中的斜杠
sed 's|/usr/local|/usr|g' file.txt

# 删除行尾的空格
sed 's/[[:space:]]*$//' file.txt

# 删除行首的空格
sed 's/^[[:space:]]*//' file.txt
删除操作
# 删除包含pattern的行
sed '/pattern/d' file.txt

# 删除第N行
sed 'Nd' file.txt
sed '5d' file.txt                 # 删除第5行

# 删除范围
sed '2,5d' file.txt               # 删除2-5行
sed '10,$d' file.txt              # 删除第10行到最后

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

# 删除注释行(以#开头)
sed '/^#/d' file.txt
打印操作
# 打印匹配的行(通常与-n选项一起使用)
sed -n '/pattern/p' file.txt

# 打印范围
sed -n '2,5p' file.txt            # 打印2-5行

# 打印奇数行
sed -n '1~2p' file.txt

# 打印偶数行
sed -n '2~2p' file.txt
追加、插入和替换行
# 在匹配行后追加
sed '/pattern/a\追加的内容' file.txt

# 在匹配行前插入
sed '/pattern/i\插入的内容' file.txt

# 替换整行
sed '/pattern/c\新的内容' file.txt

高级用法

多命令执行
# 使用多个-e选项
sed -e 's/foo/bar/g' -e '/^#/d' file.txt

# 使用分号分隔
sed 's/foo/bar/g; /^#/d' file.txt

# 使用多个表达式
sed -e 's/foo/bar/g' -e 's/hello/world/g' file.txt
使用保持空间
# 反转文件行序
sed '1!G;h;$!d' file.txt

# 每两行合并为一行
sed 'N;s/\n/ /' file.txt
分组和反向引用
# 使用基本正则表达式分组
sed 's/\(foo\) \(bar\)/\2 \1/' file.txt

# 使用扩展正则表达式(-r)
sed -r 's/(foo) (bar)/\2 \1/' file.txt

# 日期格式转换
echo "2023-12-25" | sed -r 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/'

注:

grep ,awk ,sed的处理逻辑是什么?

工具处理模型核心逻辑适用场景
grep行过滤模型逐行扫描,匹配模式,输出匹配的行文本搜索、过滤
awk字段处理模型按字段分割,编程式处理,支持复杂逻辑结构化数据处理、报表生成
sed流编辑模型逐行读取,执行编辑命令,输出结果文本转换、批量编辑
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值