IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

bash shell - sed及awk文本捕获及替换

rank's technical notes 2011-06-24 14:03:16 累计浏览 4,298 次
本机暂存
bash shell虽然支持正则表达式, 但是正则操作却不大给力.
看以下示例

case需求.
stream='background-image: url (a.jpg)asdfasdfasdf ;background:url(b.jpg);background'
需要将背景图片内容a.jpg及b.jpg后追加一个签名串.

sed替换不给力
如果用sed, 替换是不会有问题, 但是要在一句代码里进行捕获多个图, 将进行替换, 查阅了相关的sed文档, 貌似是需求处理不了.
代码示例
stream='background-image: url (a.jpg)asdfasdfasdf ;background:url(b.jpg);background'
echo $stream | sed 's#.*url *( *\(.*\) *).*#\1#'

#输出b.jpg

awk代码块
用awk的话,(g)sub又没有sed里的匹配后的"后向引用"(即"\1"). 但是可以有代码块可操作.
原理可利用awk里的函数match先用正则匹配url()里的内容, 再用substr将内容取出, 随之将流的位置置后.
循环操作.
代码如下:
stream='background-image: url (a.jpg)asdfasdfasdf ;background:url(b.jpg);background'

matches=$(echo $stream | awk 'BEGIN {ORS=" "} END {
 gsub(/ */,"", $0)
 input=$0
 while (match(input, "url([^?;)]+)")) {
 print substr(input, RSTART+4, RLENGTH-4)
 input=substr(input, RSTART+RLENGTH)
 }
}')

for bg_file in `echo "${matches}"`; do
 md5_code="test"
 stream=$(echo "${stream}" | sed "s#url *( *${bg_file} *)#url(${bg_file}?v=${md5_code})#")
done

echo "${stream}"

总结
从以上的示例可以看出, awk几乎可以替代sed, 但是对于固定替换, sed使用起来更方便.
sed从使用理解上看, 与vi的命令操作很相似.
而在awk里块里几乎可以操作任意文本流.
另外要说明的是, 这两个命令所支持的正则都像是标准perl里的子集, 没有贪婪匹配与非贪婪匹配之分.
其实你应该很意外, 我为什么不用python或者php这种语言来写, 如果用字符串函数比较多的语言来写的话, 应该是非常之简单.
很遗憾也很高兴的, 这次有点钻牛角尖, 依然用了bash.
也算为学bash打下个基础.

同分类推荐文章

  1. 从零重建 macOS 开发机:可复现的环境初始化流程 (2026-06-14 20:36:00)
  2. 百度物理网络监控工具开源第二弹:毫秒级监控工具 baize,让你的网络问题无处遁形 (2026-06-11 08:10:28)
  3. How to Set Up Homebrew Tap for Private CLI Tools: A Complete Guide (2026-05-27 02:13:03)

查看更多 DevOps 文章 →

建议继续学习

  1. Bash的模式和配置文件加载 (累计阅读 24,406)
  2. 28个Unix/Linux的命令行神器 (累计阅读 16,790)
  3. 高效Linux用户需要了解的命令行技能 (累计阅读 12,823)
  4. linux 建立两台机器的信任关系 (累计阅读 11,483)
  5. 利用find和sed批量替换文件内容 (累计阅读 11,458)
  6. 利用脚本分析日志并利用snmp自定义OID,再通过cacti画图 (累计阅读 10,068)
  7. linux中设置alias永久生效 (累计阅读 9,604)
  8. AWK 简明教程 (累计阅读 9,366)
  9. Bash脚本15分钟进阶教程 (累计阅读 9,059)
  10. 你可能不知道的Shell (累计阅读 8,311)