在我的bash
脚本中,我有一个字符串及其前缀/后缀。我需要从原始字符串中删除前缀/后缀。
例如,假设我有以下值:
string="hello-world"
prefix="hell"
suffix="ld"
我如何得到以下结果?
result="o-wor"
在我的bash
脚本中,我有一个字符串及其前缀/后缀。我需要从原始字符串中删除前缀/后缀。
例如,假设我有以下值:
string="hello-world"
prefix="hell"
suffix="ld"
我如何得到以下结果?
result="o-wor"
$ foo=${string#"$prefix"}
$ foo=${foo%"$suffix"}
$ echo "${foo}"
o-wor
这记录在手册的Shell Parameter Expansion部分:
${parameter#word}
${parameter##word}
该词被扩展以产生一个模式并根据下面描述的规则进行匹配(请参阅模式匹配)。如果模式匹配参数扩展值的开头,则扩展的结果是删除了最短匹配模式(
#
案例)或最长匹配模式(案例)的参数扩展值。##
[…]
${parameter%word}
${parameter%%word}
该词被扩展以产生一个模式并根据下面描述的规则进行匹配(请参阅模式匹配)。如果模式匹配参数扩展值的尾随部分,则扩展的结果是删除了最短匹配模式(
%
案例)或最长匹配模式(案例)的参数值。%%
[…]
Using sed:
$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor
Within the sed command, the ^
character matches text beginning with $prefix
, and the trailing $
matches text ending with $suffix
.
Adrian Frühwirth makes some good points in the comments below, but sed
for this purpose can be very useful. The fact that the contents of $prefix and $suffix are interpreted by sed can be either good OR bad- as long as you pay attention, you should be fine. The beauty is, you can do something like this:
$ prefix='^.*ll'
$ suffix='ld$'
$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor
which may be what you want, and is both fancier and more powerful than bash variable substitution. If you remember that with great power comes great responsibility (as Spiderman says), you should be fine.
A quick introduction to sed can be found at http://evc-cit.info/cit052/sed_tutorial.html
A note regarding the shell and its use of strings:
For the particular example given, the following would work as well:
$ echo $string | sed -e s/^$prefix// -e s/$suffix$//
...but only because:
It's generally good practice to quote a string on the command line because even if it contains spaces it will be presented to the command as a single argument. We quote $prefix and $suffix for the same reason: each edit command to sed will be passed as one string. We use double quotes because they allow for variable interpolation; had we used single quotes the sed command would have gotten a literal $prefix
and $suffix
which is certainly not what we wanted.
Notice, too, my use of single quotes when setting the variables prefix
and suffix
. We certainly don't want anything in the strings to be interpreted, so we single quote them so no interpolation takes place. Again, it may not be necessary in this example but it's a very good habit to get into.
你知道你的前缀和后缀的长度吗?在你的情况下:
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 的解决方案非常酷!我不知道!
$ 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”将被到处删除,即使它在中间被发现。
我使用 grep 从路径中删除前缀(这不是很好处理的sed
):
echo "$input" | grep -oP "^$prefix\K.*"
\K
从匹配中删除它之前的所有字符。
使用=~
运算符:
$ string="hello-world"
$ prefix="hell"
$ suffix="ld"
$ [[ "$string" =~ ^$prefix(.*)$suffix$ ]] && echo "${BASH_REMATCH[1]}"
o-wor
小而通用的解决方案:
expr "$string" : "$prefix\(.*\)$suffix"
使用@Adrian Frühwirth 回答:
function strip {
local STRING=${1#$"$2"}
echo ${STRING%$"$2"}
}
像这样使用它
HELLO=":hello:"
HELLO=$(strip "$HELLO" ":")
echo $HELLO # hello
注意:不确定这在 2013 年是否可行,但今天(2021 年 10 月 10 日)肯定可行,因此添加另一个选项...
由于我们正在处理已知的固定长度字符串 (prefix
和suffix
),我们可以使用bash
子字符串通过单个操作获得所需的结果。
输入:
string="hello-world"
prefix="hell"
suffix="ld"
计划:
bash
子字符串语法:${string:<start>:<length>}
prefix="hell"
意味着我们的<start>
意志4
<length>
将是string
( ${#string}
) 的总长度减去我们的固定长度字符串的长度 ( 4
for hell
/ 2
for ld
)这给了我们:
$ echo "${string:4:(${#string}-4-2)}"
o-wor
注意:可以删除括号并仍然获得相同的结果
如果 和 的值prefix
未知suffix
或可能不同,我们仍然可以使用相同的操作,但分别用和替换4
和:2
${#prefix}
${#suffix}
$ echo "${string:${#prefix}:${#string}-${#prefix}-${#suffix}}"
o-wor
我会在正则表达式中使用捕获组:
$ 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