我的子string=substr1-substr2-substr3.substr4
字符串长度可变。我想substr3
从中提取string
并正在考虑使用${string##pattern}
和${string%pattern}
字符串操作扩展来完成它。使用这种方法,很明显我需要在生成的扩展上运行${string##*-}
并运行${string%.*}
,反之亦然。我的问题是:
- 这是最好的选择吗?
- 如果是,我如何一步运行两者?当我尝试做类似
${string##*-${string%.*}}
or 的事情时${string%.*${string##*-}}
,我只是取回完整的字符串。我意识到我总是可以通过将中间变量分配给第一步的结果来分两步进行提取,然后对其进行操作;但我想一步到位。我该怎么办?
蒂亚!
答案1
给定
string=substr1-substr2-substr3.substr4
${string%.*}
是
substr1-substr2-substr3
所以,${string##*-${string%.*}}
是
${string##*-substr1-substr2-substr3}
这意味着从 开始删除string
直到并包括 的所有内容-substr1-substr2-substr3
。但是 中没有这样的子字符串string
,因为 前面没有破折号substr1
,所以你得到了原始字符串。
你可能想要的是
string=substr1-substr2-substr3.substr4
result="${string%.*}"
result="${result##*-}"
这导致result
包含substr3
。
在 Zsh 中,您可以一步完成:result=${${string%.*}##*-}
,但这在 Bash 中不起作用。
#
在 Bash 中,您只能在or的右侧使用扩展%
,这对您没有帮助,因为您需要从字符串的开头和结尾删除部分。
或者,如果$string
不包含换行符,您可以使用
IFS=.- read -r a b c d <<< "$string"
并substr3
从 中读出c
。
在这种情况下,根据 shell 和字符串的大小, 的内容$string
将存储在临时文件中或通过管道馈送,该管道read
将读取第一行并根据 拆分它$IFS
。
答案2
这个问题是关于 bash 的,但对于任何使用 Zsh 并通过搜索遇到这个问题的人来说......这可能会有所帮助。
仅限 Zsh 的答案...
...也许还有其他 shell,但不是 bash (5.1.16)
要在 Zsh 上进行多个字符串替换,您可以嵌套参数扩展:
string=substr1-substr2-substr3.substr4
result=${${string##*-}%.*}