Tim*_*Tim 4 bash wildcards brace-expansion
假设在工作目录中,只有一个 djvu 文件。我想将文件备份到文件名.bk末尾有额外内容的文件中。cp *.djvu{,.bk}将 djvu 文件复制到名为*.djvu.bk. 为什么*在备份文件名中没有展开?怎么会这样?
发生的情况是 bash 首先扩展*.djvu{,.bk}为*.djvu
*.djvu.bk,然后对它们进行全局扩展。这将解释您观察到的内容:在您的情况下,*.djvu, 匹配现有文件,比如说foo.djvu并扩展为该*.djvu.bk文件,但不匹配任何文件,因此扩展为自身,*.djvu.bk.
bash 文档中指定了扩展顺序:
The order of expansions is: brace expansion, tilde expansion, parame?
ter, variable and arithmetic expansion and command substitution (done
in a left-to-right fashion), word splitting, and pathname expansion.
Run Code Online (Sandbox Code Playgroud)
我建议将您的复制命令重写为:
for f in *.djvu; do cp -- "$f" "$f".bk; done
Run Code Online (Sandbox Code Playgroud)
或者,为了避免显式 for 循环的语法开销:
parallel -j1 cp -- {} {}.bk ::: *.djvu
Run Code Online (Sandbox Code Playgroud)
(再想一想……这并不算短。)
要回答您的子问题“如何扩展”,可以使用子命令(例如,在仅包含foo.djvu和
的目录中bar.djvu):
$ echo $(echo *.djvu){,.bk}
bar.djvu foo.djvu bar.djvu foo.djvu.bk
Run Code Online (Sandbox Code Playgroud)
但这并不像上面的 for 循环或并行调用那样安全;它将分解包含空格的文件名。