Bash替换//不处理像Regex这样的锚点?因为它是类似于全球的

时间:2017-10-19 18:37:33

标签: bash

因此,目标是使用提供的regexp替换部分路径名库。 我想使用内置的regexp替换器$ {path // src / dest}

/tmp/some\/where/ is somewhat crude, as my_tmp would be matched to stupidity
/\/tmp\//\/somewhere\// is better
/^\/tmp\//\/somewhere\// is the best, but this last one doesn't seem to work.

一个更简单的例子,因为那些反斜杠转义是杀手:

$ t2="there hello"
$ t1="hello there"
$ echo ${t1//hello/goodbye}
    goodbye there
$ echo ${t2//hello/goodbye}
    there goodbye

但是我要说我只想要开始你好:

$ echo ${t2//^hello/goodbye}
    there hello            -- as required

$ echo ${t1//^hello/goodbye}
    hello there            -- but not what I want here

-- ok let's try oldschool
$ echo ${t2//~hello/goodbye}
    there hello            -- as required

$ echo ${t1//~hello/goodbye}
    hello there            -- but not what I want here

$ t3="^hello there"

$ echo ${t3//^hello/goodbye}
    goodbye there       -- ^ is just a character :-(

但是怎么样=〜,我听到你问......

$ if [[ $t1 =~ ^hello ]] ; then echo yes ; else echo no ; fi
    yes

$ if [[ $t2 =~ ^hello ]] ; then echo yes ; else echo no ; fi
    no

$ if [[ $t3 =~ ^hello ]] ; then echo yes ; else echo no ; fi
    no

所以,基本上=〜和$ {//

之间的行为有所不同

我想我可以用某种方式使用=〜和$ BASH_REMATCH?

使用sed我得到了预期的答案,但我真的不想调用外部代码:

$ echo $t1 | sed s/^hello/goodbye/
    goodbye there
$ echo $t2 | sed s/^hello/goodbye/
    there hello
$ echo $t3 | sed s/^hello/goodbye/
    ^hello there

GNU bash,版本4.3.48(1)-release(x86_64-pc-linux-gnu)

1 个答案:

答案 0 :(得分:3)

bash manual(强调添加):

  

${parameter/pattern/string}

  • 扩展模式以生成与文件名扩展一样的模式。 参数已展开, pattern 与其值的最长匹配将替换为 string 。如果 pattern 以'/'开头,则 pattern 的所有匹配项都将替换为 string 。通常只替换第一场比赛。 如果模式以“#”开头,​​则必须在参数 的扩展值的开头匹配。如果 pattern 以'%'开头,则必须在参数的扩展值的末尾匹配。

请注意,对锚定模式执行重复搜索和替换是没有意义的,因为锚定模式只能匹配一次。因此,///#互不兼容。 (或者,更准确地说,#中的${pattern//#.../...}未得到特别处理。)

正如手册所说,pattern是一个glob,而不是正则表达式,因此它遵循与filename expansion相同的逻辑。设置extglob将允许使用"扩展模式匹配字符",这使得类似正则表达式的模式成为可能。

证据在布丁中:

$ t1="hello there"
$ t2="there hello"
$ echo ${t1/#hello/goodbye}
goodbye there
$ echo ${t2/#hello/goodbye}
there hello