Linux 三剑客之 sed 高级用法 模式替换

在 sed 的基本用法里面介绍了替换命令 s,例如 将 " sed command replacement test" 中的 test 替换成 trial 
echo " sed command replacement test " | sed 's/test/trial/

在这里插入图片描述
上面这种将一个 固定 字符串 替换 成另外一个字符串 相对比较简单,下面将介绍两种更有趣的替换。

  1. 单模式替换,可以 使用 & 来 存储 被匹配部分的值以供后面复用,& 相当于一个变量 。
    例如,有一个通讯录 contact.txt:
 zhangyu      singer   M  720527430  yongxinliangku
 liangchaowei actor    M  255376932  wujiandao
 zhouhuiming  singer   F  248420369  zuiai
 zhouxingchi  director M  325851914  kongfu

需求是:将第四列的9位数qq号修改成qq 邮箱 即 720527430 换成 720527430@qq.com
实现代码:

# [0-9] 为正则表达 数字集 
# [0-9]{9} 为正则表达式,表示 9 个数字,{n} 表示前面的字符重复 n 次
# & 为 sed 里面的 模式表达式,表示被匹配的内容
# {} 与 . 这两个字符 需要使用 \ 进行转义
# &@qq\.com 就是 在 匹配的 内容后面加上 @qq.com

sed 's/[0-9]\{9\}/&@qq\.com/' contact.txt


命令运行结果:
在这里插入图片描述

  1. 子模式替换,使用 () 符号 将 匹配内容 划分成 若干部分,然后再 使用 \n 来 引用 相应的 第 n 部分 值。例如, 在 (720527430)@(qq.com) 就包含了 (720527430) 和 (qq.com) 子部分,\1 引用 720527430 , \2 引用 qq.com
echo "zhangyu      singer   M  720527430@qq.com  yongxinliangku"
# 结果 zhangyu      singer   M  720527430@qq.com  yongxinliangku
echo "zhangyu      singer   M  720527430@qq.com  yongxinliangku" | sed 's/\(720527430\)@\(qq\.com\)/account/'
# () 和 . 这两个符号 需要使用 \ 转义, 这个替换将 使用  account 替换 720527430@qq.com , 运行结果是: zhangyu      singer   M  account  yongxinliangku 
echo "zhangyu      singer   M  720527430@qq.com  yongxinliangku" | sed 's/\(720527430\)@\(qq\.com\)/\1account/'
# \1 引用 (720527430)@(qq.com) 中 的 第一部分, 即 \1=720527430 , 所以 \1account 就是 720527430account, 运行结果是:zhangyu      singer   M  720527430account  yongxinliangku
echo "zhangyu      singer   M  720527430@qq.com  yongxinliangku" | sed 's/\(720527430\)@\(qq\.com\)/\2account/'
# \2 引用 (720527430)@(qq.com) 中 的 第二部分, 即 \2=qq.com , 所以 \2account 就是 qq.comaccount, 运行结果是: zhangyu      singer   M  qq.comaccount  yongxinliangku


实践部分
有一个雇员 数据库 emp.dat ,emp.dat 有15条记录,每条记录包含7个字段: First name, Last name, Phone number, Email address, Gender, Department, Salary。 由于工作人员操作不当,导致记录“追尾”,即后一条记录的 Fist name 咬住了 前一条记录的 Salary 。原本15条记录变成了1条记录。请你将 emp.dat 里面的 Salary 与 First name 两个字段用 换行符分开,恢复成 15条记录。

# 原始数据
Jack    Singh   9857532312  jack@gmail.com      M   hr      2000Jane    Kaur    9837432312  jane@gmail.com      F   hr          1800Eva     Chabra  8827232115  eva@gmail.com       F   lgs     2100Amit    Sharma  9911887766  amit@yahoo.com      M       lgs     2350Julie   Kapur   8826234556  julie@yahoo.com     F   Ops     2500Ana     Khanna  9856422312  anak@hotmail.co    m    F   Ops     2700Hari    Singh   8827255666  hari@yahoo.com      M   Ops     2350Victor  Sharma  8826567898  vics@hot    mail.com    M   Ops     2500John    Kapur   9911556789  john@gmail.com      M   hr      2200Billy   Chabra  9911664321  b    ily@yahoo.com      M   lgs     1900Sam     khanna  8856345512  sam@hotmail.com     F   lgs     2300Ginny   Singh   985712    3466  ginny@yahoo.com     F   hr      2250Emily   Kaur    8826175812  emily@gmail.com     F   Ops     2100Amy     Sharma      9857536898  amys@hotmail.com    F   Ops     2500Vina    Singh   8811776612  vina@yahoo.com      F   lgs     2300

# 需求转换成代码 即 在  2000Jane 的 中间 加 一个 \n  符, Salary 为 4 位数字,匹配正则 [0-9]{4}, First name 为长度大于等于3的字母串,匹配正则 [a-zA-Z]{3,} 。 使用子模式替换,\1 替换 Salary, \2 替换 First name. () 与 {} 需要使用 \ 转义, 另外  全部的 Salary+First name 都要替换,所以 需要在命令后面加上标记 g 表示替换全部
 
sed 's/\([0-9]\{4\}\)\([a-zA-Z]\{3,\}\)/\1\n\2/g' emp.dat

# 运行结果
Jack    Singh   9857532312  jack@gmail.com      M   hr      2000
Jane    Kaur    9837432312  jane@gmail.com      F   hr      1800
Eva     Chabra  8827232115  eva@gmail.com       F   lgs     2100
Amit    Sharma  9911887766  amit@yahoo.com      M   lgs     2350
Julie   Kapur   8826234556  julie@yahoo.com     F   Ops     2500
Ana     Khanna  9856422312  anak@hotmail.com    F   Ops     2700
Hari    Singh   8827255666  hari@yahoo.com      M   Ops     2350
Victor  Sharma  8826567898  vics@hotmail.com    M   Ops     2500
John    Kapur   9911556789  john@gmail.com      M   hr      2200
Billy   Chabra  9911664321  bily@yahoo.com      M   lgs     1900
Sam     khanna  8856345512  sam@hotmail.com     F   lgs     2300
Ginny   Singh   9857123466  ginny@yahoo.com     F   hr      2250
Emily   Kaur    8826175812  emily@gmail.com     F   Ops     2100
Amy     Sharma  9857536898  amys@hotmail.com    F   Ops     2500
Vina    Singh   8811776612  vina@yahoo.com      F   lgs     2300

#employinf原始数据

Jack 9857532312 jack@gmail.com hr 2000 5Jane 9837432312 jane@gmail.com hr 1800 5Eva 8827232115 eva@gmail.com lgs 2100 6amit 9911887766 amit@yahoo.com lgs 2350 6Julie 8826234556 julie@yahoo.com hr 2500 5

需求:原文本中,前一个员工的部门编号跟后一个同事的姓名咬到一个块了,应该每个员工的信息单独为一条记录。请将文本中’5Jane’, ‘5Eva’, ‘6amit’, ‘6Julie’ 分开成数字+换行+字母的形式

sed 's/\([[:digit:]]\)\([[:alpha:]]\)/\1\n\2/g' employinf

在这里插入图片描述

总结
单模式替换使用 & 来引用 匹配内容,子模式 使用 \1, \2, \3 …等来引用相应部分的内容,在正则表达式中使用 () 切分 子匹配模式,注意 {}, () 等特殊字符需要 使用 \ 转义

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值