V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
gangkui2008
V2EX  ›  问与答

ksh中如何用sed替换多个特殊字符(如[].等)?

  •  
  •   gangkui2008 · 2011-12-21 10:56:07 +08:00 · 11422 次点击
    这是一个创建于 4714 天前的主题,其中的信息可能已经有所发展或是发生改变。
    语句中存在[].*+等特殊字符,想把这些特殊字符全部替换为“\原字符”(木有引号),sed语句该怎么写?
    我想到的笨一点的办法是用多个管道,比如echo []. | sed 's#\[#\\&#g' | sed 's#\]#\\&#g' | sed 's#\.#\\&#g'是可以成功的,但我更想知道如何在一条sed语句中匹配多个特殊字符(可能会用|或[]吧)
    另外请特别注意我用的是ksh(AIX的缺省shell),sed在ksh和bash中的使用方法略有不同,比如echo []. |sed -e 's/\[\|\]\|\./zzz/g'在bash中的结果是zzzzzzzzz,但在ksh中结果是[].,即sed没有匹配到任何一个字符。

    另外还有一个问题是用grep检索文件时,如果给出的关键词含有特殊字符时(当然希望grep不要把它当做特殊字符处理),比较好的处理办法是什么,除了用sed匹配后在字符前加\?



    >uname -v
    6
    [root@bruce3]/wideopen/stone
    >oslevel -r
    6100-01
    [root@bruce3]/wideopen/stone
    >echo $0
    -ksh
    12 条回复    1970-01-01 08:00:00 +08:00
    gangkui2008
        1
    gangkui2008  
    OP
       2011-12-21 11:06:52 +08:00
    >echo []. | sed 's#\[\|\]\|\.#zzz#g'
    [].
    [root@bruce3]/wideopen/stone
    >echo []. | sed 's#[\[\]\.]#zzz#g'
    [].
    gastlygem
        2
    gastlygem  
       2011-12-21 11:37:04 +08:00
    是这个意思吗?俺是cygwin下的ksh加上gnu sed,没你的环境,不知道灵不灵:

    >echo []. | sed -r 's!(\[|\]|\.)!\\\1!g'
    \[\]\.
    gangkui2008
        3
    gangkui2008  
    OP
       2011-12-21 11:46:22 +08:00
    @gastlygem 还是不行,

    >echo []. | sed -r 's!(\[|\]|\.)!\\\1!g'
    sed: Not a recognized flag: r
    Usage: sed [-n] Script [File ...]
    sed [-n] [-e Script] ... [-f Script_file] ... [File ...]
    [root@bruce3]/wideopen/stone
    >echo []. | sed 's!(\[|\]|\.)!\\\1!g'
    sed: 0602-404 Function s!(\[|\]|\.)!\\\1!g cannot be parsed.
    [root@bruce3]/wideopen/stone
    >echo []. | sed 's/(\[|\]|\.)/\\&/g'
    [].
    [root@bruce3]/wideopen/stone
    >echo []. | sed 's/(\[|\]|\.)/zzz/g'
    [].
    ratazzi
        4
    ratazzi  
       2011-12-21 12:30:42 +08:00
    @gangkui2008
    echo []. | sed 's!\(\[\|\]\|\.\)!\\\1!g'
    | 也需要转义

    @gastlygem
    AIX 应该是类似 BSD 的 sed 没有 GNU sed -r 的扩展正则
    gastlygem
        5
    gastlygem  
       2011-12-21 12:32:07 +08:00
    果然 AIX 带的不是 gnu sed,不支持 -r。你还是使用多个管道符吧,又好读又好看 :D
    gangkui2008
        6
    gangkui2008  
    OP
       2011-12-21 12:51:13 +08:00
    @ratazzi
    还是不行
    >echo []. | sed 's!\(\[\|\]\|\.\)!\\\1!g'
    [].
    ratazzi
        7
    ratazzi  
       2011-12-21 12:56:44 +08:00
    @gangkui2008
    抱歉手里没有环境,也没办法了
    gangkui2008
        8
    gangkui2008  
    OP
       2011-12-21 13:02:04 +08:00
    @ratazzi
    thx all the same
    ratazzi
        9
    ratazzi  
       2011-12-21 13:10:56 +08:00
    @gangkui2008
    echo []. | sed 's/\[/\\\[/g;s/\]/\\\]/g;s/\./\\\./g'
    这种写法应该适用与大多数 UNIX,避免多个管道
    gangkui2008
        10
    gangkui2008  
    OP
       2011-12-21 13:45:51 +08:00
    @ratazzi
    good, thx
    dreamersdw
        11
    dreamersdw  
       2011-12-21 14:28:50 +08:00
    使用 fgrep (或者 grep -F)搜索时,不会转义 pattern 中的字符。
    gangkui2008
        12
    gangkui2008  
    OP
       2011-12-21 15:31:33 +08:00
    @dreamersdw
    cool! 万分感谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2783 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 12:37 · PVG 20:37 · LAX 04:37 · JFK 07:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.