我想从字符串中删除前缀/后缀。例如,给定:

string="hello-world"
prefix="hell"
suffix="ld"

如何得到以下结果?

"o-wor"

当前回答

你知道你的前缀和后缀的长度吗?在你的情况下:

result=$(echo $string | cut -c5- | rev | cut -c3- | rev)

或者更一般地说:

result=$(echo $string | cut -c$((${#prefix}+1))- | rev | cut -c$((${#suffix}+1))- | rev)

但是Adrian Frühwirth的解决方案非常酷!我不知道!

其他回答

我使用grep从路径中删除前缀(sed处理不好):

echo "$input" | grep -oP "^$prefix\K.*"

\K从匹配中删除它之前的所有字符。

小而通用的解决方案:

expr "$string" : "$prefix\(.*\)$suffix"

使用sed:

$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor

在sed命令中,^字符匹配以$前缀开头的文本,后面的$匹配以$后缀结尾的文本。

Adrian Frühwirth在下面的评论中提出了一些很好的观点,但是sed对于这个目的非常有用。sed可以解释$prefix和$suffix的内容,这一事实可能是好的,也可能是坏的——只要您注意,就不会有问题。美妙之处在于,你可以这样做:

$ prefix='^.*ll'
$ suffix='ld$'
$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor

这可能是您想要的,而且比bash变量替换更漂亮、更强大。如果你记得能力越大责任越大(正如蜘蛛侠所说),你就会没事。

可以在http://evc-cit.info/cit052/sed_tutorial.html上找到sed的快速介绍

关于shell及其字符串使用的注意事项:

对于给定的特定示例,下面的代码也可以使用:

$ echo $string | sed -e s/^$prefix// -e s/$suffix$//

...但这只是因为:

Echo并不关心参数列表中有多少字符串 $前缀和$后缀中没有空格

在命令行上引用字符串通常是一种良好的实践,因为即使它包含空格,它也将作为单个参数显示给命令。我们引用$prefix和$suffix是出于同样的原因:将每个编辑命令作为一个字符串传递给sed。我们使用双引号是因为它们允许变量内插;如果我们使用单引号,sed命令将得到一个字面的$前缀和$后缀,这当然不是我们想要的。

还要注意,我在设置变量前缀和后缀时使用了单引号。我们当然不希望字符串中的任何内容被解释,所以我们对它们进行单引号,这样就不会发生插值。同样,在这个例子中可能没有必要,但这是一个很好的习惯。

对阿德里安早餐满意:

function strip {
    local STRING=${1#$"$2"}
    echo ${STRING%$"$2"}
}

像这样使用它

HELLO=":hello:"
HELLO=$(strip "$HELLO" ":")
echo $HELLO # hello
$ string="hello-world"
$ prefix="hell"
$ suffix="ld"

$ #remove "hell" from "hello-world" if "hell" is found at the beginning.
$ prefix_removed_string=${string/#$prefix}

$ #remove "ld" from "o-world" if "ld" is found at the end.
$ suffix_removed_String=${prefix_removed_string/%$suffix}
$ echo $suffix_removed_String
o-wor

注:

#$prefix:添加#确保子字符串“hell”只在开头被发现时才被删除。 %$后缀:添加%确保子字符串“ld”只有在end中找到时才会被删除。

如果没有这些,子字符串“hell”和“ld”将被删除,即使它是在中间找到的。