我想将位于远程计算机上的文件复制到本地计算机上,其文件名与前缀字符串匹配。
我尝试使用以下命令仅选择名称以massif
或开头的文件:calgrind
scp my-machine:/home/user/a-folder/[massif,callgrind]* .
但是,此表达式允许匹配空字符串加上任意数量的字符,因此匹配与目录相关的所有文件名。
我需要更改什么才能使其正常工作?
答案1
听起来你想要大括号:
scp my-machine:/home/user/a-folder/{massif,callgrind}* .
否则,您将匹配单个字符,而不是两个完整的字符串。
bash
进行多种不同类型的扩展和替换;这些记录在 bash 手册页 - 查找部分EXPANSION
。在这里,该[
类型包含在“路径名扩展”(它匹配路径名)和{
“大括号扩展”(它从提供的选项中生成多个参数,无论存在什么文件)下。
答案2
可以使用两种方法来选择文件:可以连续或相继指定模式。
第一种方法
该方法需要使用一个Bash 扩展模式一起指定多个模式。用户必须extglob
使用shopt
内置命令启用 shell 选项(参见shopt
内置)因为默认情况下不启用 Bash 扩展模式。
prompt% scp username@hostname:"/home/user/dirname/@(foo|bar)*" .
Bash 子模式@(PATTERN-LIST)
允许指定由 分隔的一个或多个模式的列表|
。它与给定模式之一匹配。例如,@(foo|bar)
匹配foo
或bar
但不匹配foobar
, barfoo
, foofoo
, barbar
。
全局星号匹配任何字符串,包括空字符串。因此,该模式@(foo|bar)*
匹配所有以foo
or bar
(前缀(子)字符串)开头的文件名。
当远程 shell 是 Bash 并且extglob
启用了其 shell 选项时,此方法有效。用户可以在~/.bash_profile
远程计算机上的配置文件(例如 )中启用此 Bash 选项。
第二种方法
此方法使用不同的参数多次执行相同的命令。它使用符合 POSIX 标准的 shell 工作。
for prefix in foo bar
do
scp username@hostname:"/home/user/dirname/${prefix}*" .
done
支撑扩张
此方法并不可靠,因为结果表达式可能指定不存在的文件名。