Unix Shell 中最短子字符串匹配的概念是什么?

Unix Shell 中最短子字符串匹配的概念是什么?

我在字符串处理中使用以下脚本进行最短子字符串匹配。

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,则必须删除字符串.stringstring.从字符串中间删除。这可以通过标准参数扩展分两步完成:

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 的左侧.。该表示法将所有内容截断到第一个点。

相关内容