在我的bash脚本中,我有一个字符串及其前缀/后缀.我需要从原始字符串中删除前缀/后缀.
例如,假设我有以下值:
string="hello-world"
prefix="hell"
suffix="ld"
Run Code Online (Sandbox Code Playgroud)
我如何得到以下结果?
result="o-wor"
Run Code Online (Sandbox Code Playgroud)
Adr*_*rth 641
$ foo=${string#"$prefix"}
$ foo=${foo%"$suffix"}
$ echo "${foo}"
o-wor
Run Code Online (Sandbox Code Playgroud)
Chr*_*din 80
使用sed:
$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor
Run Code Online (Sandbox Code Playgroud)
在sed命令中,^字符匹配以?开头的文本$prefix,尾随$匹配以$suffix.结尾的文本.
AdrianFrühwirth在下面的评论中提出了一些好处,但sed为此目的可能非常有用.$ sed和$ suffix的内容由sed解释的事实可能是好的或坏的 - 只要你注意,你应该没事.美丽的是,你可以这样做:
$ prefix='^.*ll'
$ suffix='ld$'
$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor
Run Code Online (Sandbox Code Playgroud)
这可能是你想要的,并且比bash变量替换更有魅力和更强大.如果你记得有很大的力量就会有很大的责任(正如蜘蛛侠说的那样),你应该没事.
有关sed的快速介绍,请访问http://evc-cit.info/cit052/sed_tutorial.html
关于shell及其字符串使用的注释:
对于给出的特定示例,以下内容也可以使用:
$ echo $string | sed -e s/^$prefix// -e s/$suffix$//
Run Code Online (Sandbox Code Playgroud)
......但仅仅是因为:
在命令行上引用字符串通常是一种好习惯,因为即使它包含空格,它也会作为单个参数显示给命令.我们引用$ prefix和$ suffix的原因相同:sed的每个edit命令都将作为一个字符串传递.我们使用双引号,因为它们允许变量插值; 如果我们使用单引号,sed命令会得到一个字面值$prefix,$suffix这肯定不是我们想要的.
还请注意,我设置的变量时,使用单引号prefix和suffix.我们当然不希望对字符串中的任何内容进行解释,因此我们单引引它们以便不进行插值.同样,在这个例子中可能没有必要,但这是一个非常好的习惯.
tom*_*sen 15
你知道你的前缀和后缀的长度吗?在你的情况下:
result=$(echo $string | cut -c5- | rev | cut -c3- | rev)
Run Code Online (Sandbox Code Playgroud)
或者更一般:
result=$(echo $string | cut -c$((${#prefix}+1))- | rev | cut -c$((${#suffix}+1))- | rev)
Run Code Online (Sandbox Code Playgroud)
但AdrianFrühwirth的解决方案很酷!我不知道那个!
Vla*_*ich 14
我使用grep从路径中删除前缀(没有很好地处理sed):
echo "$input" | grep -oP "^$prefix\K.*"
Run Code Online (Sandbox Code Playgroud)
\K 从匹配中删除之前的所有字符.
$ 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
Run Code Online (Sandbox Code Playgroud)
#$ prefix:添加#确保仅在开头找到子字符串“ hell”。%$ suffix:添加%可以确保仅在结尾找到子字符串“ ld”。
没有这些,子字符串“ hell”和“ ld”将在所有位置删除,即使在中间也可以找到。
注意:不确定这在 2013 年是否可能,但今天(2021 年 10 月 10 日)肯定有可能,因此添加另一个选项......
由于我们正在处理已知的固定长度字符串(prefix和suffix),因此我们可以使用bash子字符串通过单个操作获得所需的结果。
输入:
string="hello-world"
prefix="hell"
suffix="ld"
Run Code Online (Sandbox Code Playgroud)
计划:
bash子串语法:${string:<start>:<length>}prefix="hell"意味着我们<start>将4<length>将是string( ${#string}) 的总长度减去固定长度字符串的长度 ( 4for hell/ 2for ld)这给了我们:
$ echo "${string:4:(${#string}-4-2)}"
o-wor
Run Code Online (Sandbox Code Playgroud)
注意:可以删除括号并仍然获得相同的结果
prefix如果和 的值suffix未知,或者可能有所不同,我们仍然可以使用相同的操作,但分别将4和替换2为${#prefix}和:${#suffix}
$ echo "${string:${#prefix}:${#string}-${#prefix}-${#suffix}}"
o-wor
Run Code Online (Sandbox Code Playgroud)
使用=~运算符:
$ string="hello-world"
$ prefix="hell"
$ suffix="ld"
$ [[ "$string" =~ ^$prefix(.*)$suffix$ ]] && echo "${BASH_REMATCH[1]}"
o-wor
Run Code Online (Sandbox Code Playgroud)
使用@AdrianFrühwirth答案:
function strip {
local STRING=${1#$"$2"}
echo ${STRING%$"$2"}
}
Run Code Online (Sandbox Code Playgroud)
这样使用
HELLO=":hello:"
HELLO=$(strip "$HELLO" ":")
echo $HELLO # hello
Run Code Online (Sandbox Code Playgroud)