我在字符串处理中使用以下脚本进行最短子字符串匹配。
filename="bash.string.txt"
echo ${filename#*.}
它给出以下输出。
string.txt
这是上面示例的解释(链接:https://www.thegeekstuff.com/2010/07/bash-string-manipulation):
上面的示例删除 $string 前面 $substring 的最短匹配。在第一个 echo 语句中子字符串 '*.'匹配字符和一个点,# 会从字符串的前面剥离,因此它会剥离子字符串“bash”。来自名为 filename 的变量。
然后我将代码更改如下:
filename="bashshell.string.txt"
echo ${filename#*.}
我刚刚扩展了第一个字符串重击。到bashshell。 并根据上面给出的解释期望输出“bashshell.txt”。但它给了我与第一个示例相同的输出。
IEstring.txt
那么我是否误解了这个概念?如果是,那么它实际上是如何工作的?
答案1
本教程对“子字符串”一词的使用有点误导。当使用 时${variable#pattern}
,我们正在处理匹配和删除前缀字符串(并且${variable%pattern}
带有后缀字符串)。
*.
您从两个字符串bash.string.txt
和中删除了最短的前缀字符串匹配bashshell.string.txt
。两个字符串的结果相同,string.txt
,因为模式*.
匹配字符串中的第一个点(包括第一个点)。
POSIX 标准定义这个特定的参数扩展作为
${parameter#[word]}
删除最小前缀模式。这单词应扩大以产生图案。参数扩展将导致范围,与匹配的前缀的最小部分图案已删除。如果存在,单词不应以不带引号的 开头
#
。
如果您想获得结果bashshell.txt
,则必须删除字符串.string
或string.
从字符串中间删除。这可以通过标准参数扩展分两步完成:
suffix=${filename##*.} # remove everything to the *last* dot
echo "${filename%%.*}.$suffix" # remove everything from the first dot and add suffix
参数扩展的##
和变化消除了%%
最长分别匹配前缀和后缀字符串。
或者使用bash
:
echo "${filename/string./}"
这将删除 值内任何位置的给定字符串(第一次出现的)$filename
。
答案2
那么我是否误解了这个概念?如果是,那么它实际上是如何工作的?
是的,该表示法${var#*.}
正在删除从字符串开头到字符点 ( .
) 的所有内容。它正在按照您的要求进行操作,您的模式是星点:
*.
因此,它将匹配从字符串开头开始的第一个点(单词 后面的点)之前的所有内容bash
。
bash.string.txt
^---------------- it's splitting here
例子
$ str="bash.string.txt"
$ echo "${str#*.}"
string.txt
$ str="bash1.string.txt"
$ echo "${str#*.}"
string.txt
$ str="bash1.string1.txt"
$ echo "${str#*.}"
string1.txt
看看我何时将 1 放在 1st 的左侧.
。该表示法将所有内容截断到第一个点。