linux 如何替换POSIX sh字符串中“/”

bybem2ql  于 2023-01-08  发布在  Linux
关注(0)|答案(2)|浏览(132)

要替换bash字符串str中的子字符串,我使用:

str=${str/$pattern/$new}

但是,我目前正在编写一个将使用ash执行的脚本。
我有一个包含'/'的字符串,我想使用上面的语法来替换字符串中的'/',但它不起作用。
我试过:

str=${str///a}
str=${str/\//a}
str=${str/'/'/a}

但它们不起作用
我该怎么补救?

njthzxwz

njthzxwz1#

这个参数扩展是POSIX sh的一个bash扩展。如果您查看IEEE标准1003.1的相关部分,您会发现它不是一个必需的特性,因此只承诺POSIX兼容性的shell(如ash)没有义务实现它,并且它们的实现也没有义务遵守任何特定的正确性标准。
如果您需要bash扩展,则需要使用bash(或其他类似扩展的ksh衍生物)。
在此期间,您可以使用其他工具。例如:

str=$(printf '%s' "$str" | tr '/' 'a')

str=$(printf '%s' "$str" | sed -e 's@/@a@g')
2lpgd968

2lpgd9682#

POSIX字符串替换可以用来创建一个100% POSIX兼容的函数来进行替换。对于短字符串,这比命令替换快得多,特别是在Cygwin下,它的fork(2)复制父进程的地址空间,而在Windows中创建进程通常很慢。

replace_all() {
    RIGHT=$1
    R=

    while [ -n "$RIGHT" ]; do
        LEFT=${RIGHT%%$2*}

        if [ "$LEFT" = "$RIGHT" ]; then
            R=$R$RIGHT
            return
        fi

        R=$R$LEFT$3
        RIGHT=${RIGHT#*$2}
    done
}

它是这样工作的:

$ replace_all ' foo bar baz ' ' ' .
$ echo $R
.foo.bar.baz.

在性能方面,使用replace_all()替换512字节字符串中25%的字符比Cygwin dash(1)下的命令替换快大约50倍,但执行时间平均为4 KiB左右。

相关问题