如何获取与“*”通配符匹配的文件名的子字符串?

Mic*_*urr 5 bash wildcards

假设我有一个包含以下文件的目录(以及其他文件):

touch doc-mike.txt doc-jane.txt doc-susan.txt
Run Code Online (Sandbox Code Playgroud)

我可以使用以下结构在脚本中使用这些文件执行某些操作:

for fname in doc-*.txt; do
    echo input: ${fname}
done
Run Code Online (Sandbox Code Playgroud)

但是如果我想获得与通配符匹配的文件名的子字符串,我必须跳过一些丑陋的圈套:

for fname in doc-*.txt; do
    wildcard=${fname#doc-}
    wildcard=${wildcard%.txt}

    echo input: ${fname} output: output-${wildcard}.results
done
Run Code Online (Sandbox Code Playgroud)

那个有效:

input: doc-jane.txt output: output-jane.results
input: doc-mike.txt output: output-mike.results
input: doc-susan.txt output: output-susan.results
Run Code Online (Sandbox Code Playgroud)

但我觉得必须有更好/更简单的方法来获取与"*"glob 通配符匹配的子字符串

mur*_*uru 6

我能想到的最接近的是BASH_REMATCH,因为 bash 将正则表达式文本的结果存储在该变量中:

$ for fname in doc-*.txt; do 
    [[ $fname =~ doc-(.*).txt ]];
    echo "input: ${fname} output: output-${BASH_REMATCH[1]}.results";
done
input: doc-jane.txt output: output-jane.results
input: doc-mike.txt output: output-mike.results
input: doc-susan.txt output: output-susan.results
Run Code Online (Sandbox Code Playgroud)

由于(.*)是第一组中的正则表达式,它在BASH_REMATCH[1]。我认为这是您想要的行为,但是对于 globs,我认为 bash 不会以任何方式提供它。

  • 你也可以做类似`for fname in *; do [[ $fname =~ doc-(.*).txt ]] || 继续; ...; done` 以避免重复模式 (3认同)