阳光网驿-企业信息化交流平台【DTC零售连锁全渠道解决方案】

 找回密码
 注册

QQ登录

只需一步,快速开始

扫描二维码登录本站

手机号码,快捷登录

手机号码,快捷登录

老司机
查看: 636|回复: 0

[转帖] bash shell - sed及awk文本捕获及替换

[复制链接]
  • TA的每日心情
    郁闷
    2012-3-7 10:18
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2012-1-14 11:49:04 | 显示全部楼层 |阅读模式
    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打下个基础.
    楼主热帖
    启用邀请码注册,提高发帖质量,建设交流社区
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    快速回复 返回顶部 返回列表