从Bash中的字符串中删除固定的前缀/后缀

时间:2013-05-18 11:37:51

标签: bash

在我的bash脚本中,我有一个字符串及其前缀/后缀。我需要从原始字符串中删除前缀/后缀。

例如,假设我有以下值:

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

如何获得以下结果?

result="o-wor"

9 个答案:

答案 0 :(得分:560)

$ foo=${string#"$prefix"}
$ foo=${foo%"$suffix"}
$ echo "${foo}"
o-wor

答案 1 :(得分:74)

使用sed:

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

在sed命令中,^字符与以$prefix开头的文字匹配,尾随$匹配以$suffix结尾的文字。

AdrianFrühwirth在下面的评论中提出了一些好处,但sed为此目的非常有用。 $ sed和$ suffix的内容由sed解释的事实可能是好的或坏的 - 只要你注意,你应该没事。美丽的是,你可以这样做:

$ 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$//

...但仅仅因为:

  1. echo不关心其参数列表中有多少个字符串,
  2. $ prefix和$ suffix
  3. 中没有空格

    在命令行中引用字符串通常是一种好习惯,因为即使它包含空格,它也会作为单个参数显示给命令。我们引用$ prefix和$ suffix的原因相同:sed的每个edit命令都将作为一个字符串传递。我们使用双引号,因为它们允许变量插值;如果我们使用单引号,那么sed命令会得到一个文字$prefix$suffix,这肯定不是我们想要的。

    另请注意,我在设置变量prefixsuffix时使用了单引号。我们当然不希望对字符串中的任何内容进行解释,因此我们单引引它们以便不进行插值。同样,在这个例子中可能没有必要,但这是一个非常好的习惯。

答案 2 :(得分:14)

我使用grep从路径中删除前缀(sed没有很好地处理):

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

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

答案 3 :(得分:14)

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

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

或者更一般:

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

但是solution from Adrian Frühwirth很酷!我对此并不了解!

答案 4 :(得分:6)

小而通用的解决方案:

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

答案 5 :(得分:4)

使用@AdrianFrühwirth回答:

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

像这样使用

HELLO=":hello:"
HELLO=$(strip "$HELLO" ":")
echo $HELLO # hello

答案 6 :(得分:4)

$ 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”。 %$ suffix:添加%可以确保仅在结尾找到子字符串“ ld”。

没有这些,子字符串“ hell”和“ ld”将在各处删除,即使在中间也是如此。

答案 7 :(得分:3)

使用=~ operator

$ string="hello-world"
$ prefix="hell"
$ suffix="ld"
$ [[ "$string" =~ ^$prefix(.*)$suffix$ ]] && echo "${BASH_REMATCH[1]}"
o-wor

答案 8 :(得分:0)

我会在正则表达式中使用捕获组:

$ string="hello-world"
$ prefix="hell"
$ suffix="ld"
$ set +H # Disables history substitution, can be omitted in scripts.
$ perl -pe "s/${prefix}((?:(?!(${suffix})).)*)${suffix}/\1/" <<< $string
o-wor
$ string1=$string$string
$ perl -pe "s/${prefix}((?:(?!(${suffix})).)*)${suffix}/\1/g" <<< $string1
o-woro-wor

((?:(?!(${suffix})).)*)确保${suffix}的内容将从捕获组中排除。就示例而言,它是等效于[^A-Z]*的字符串。否则,您将得到:

$ perl -pe "s/${prefix}(.*)${suffix}/\1/g" <<< $string1
o-worldhello-wor