如何使用cp,variable和括号从不同的目录复制多个文件?

时间:2013-02-08 22:09:46

标签: bash

我的问题与How to copy multiple files from a different directory using cp?

非常相似

我不想使用显式循环。这是我的工作:

$ FILES_TOOLS="fastboot,fastboot-HW.sh"
$ cp $HOME/tools/{$FILES_TOOLS} $TOP_DIR/removeme
cp: cannot stat `/home/johndoe/tools/{fastboot,fastboot-HW.sh}': No such file or directory

文件存在且目的地有效,因为:

$ cp $HOME/tools/{fastboot,fastboot-HW.sh} $TOP_DIR/removeme
$ echo $?
0
  • 我试图从FILES_TOOLS中删除双引号,没有运气。
  • 我试图引用并引用{...},没有运气
  • 我试图反斜杠括号,没有运气
  • 我想这是实际发生shell扩展的问题。

3 个答案:

答案 0 :(得分:2)

此答案仅限于bash。

预先echo查看cp命令变成什么:

echo cp $HOME/tools/{$FILES_TOOLS} $TOP_DIR/removeme

您必须在子shell中插入eval才能使其正常工作:

cp $( eval echo $HOME/tools/{$FILES_TOOLS} ) $TOP_DIR/removeme

答案 1 :(得分:1)

  

我想这是实际发生shell扩展的问题。

是。不同的shell对于与变量扩展相关的大括号扩展有不同的规则。你的方式适用于ksh,但不适用于zsh或bash。 {1..$n}适用于ksh和zsh但不适用于bash。在bash中,变量扩展总是在大括号扩展后发生。

你在bash中最接近这一点的是eval

答案 2 :(得分:1)

只要大括号的内容是文字,您就可以使用大括号扩展来填充要复制的文件的完整路径名的数组,然后在cp命令中展开数组的内容。

$ FILES_TOOLS=( $HOME/tools/{fastboot,fastboot-HW.sh} )
$ cp "${FILES_TOOLS[@]}" $TOP_DIR/removeme

更新:我意识到你可能有理由在变量中单独使用基本名称。这是另一个基于数组的解决方案,它允许您使用路径为数组的每个元素添加前缀,同样没有显式循环:

$ FILES_TOOLS=( fastboot fastboot-HW.sh )
$ cp "${FILES_TOOLS[@]/#/$HOME/tools/}" $TOP_DIR/removeme

在这种情况下,您使用模式替换运算符将每个数组元素开头的空字符串替换为目录名。