但那里的解决方案只有在你想复制时才有效一文件。
如何将多个文件复制到尚不存在的目录中并使用一个命令自动创建它?
例如:
cd /tmp/
mkdir a/
cd a/
touch x1 x2
cp --magic * ../b/c/d/
所以最后这两个文件的顺序x1
如下x2
:
/tmp/b/c/d/x1
/tmp/b/c/d/x2
答案1
使用:
$ copy() { mkdir -p -- "${@: -1}" && cp -- "$@" ; }
$ copy * ../b/c/d/
注意:它适用于 bash、ksh93 和 zsh。
"${@: -1}"
对应于以下${parameter:offset}
形式:从偏移量开始的所有参数。偏移量 -1 对应于最后一个参数,因为负偏移量从末尾开始计数。空间是必要的,否则就是形式${parameter:-word}
。请参阅 bash 手册以获取更多信息。
"$@"
展开为参数列表,这正是 所需要的cp
。
注2:根据mikeserv的建议,您可以使用
eval 'mkdir -p -- "${'"$#"'}"'
哪个更便携(POSIX),而不是
mkdir -p -- "${@: -1}"
关于性能,eval
使用 bash 4.3.30 的解决方案要快得多,但使用 ksh 93u+ 和 zsh 5.0.6 的另一个解决方案要快得多(ksh93 和 zsh 在这两种情况下都比 bash 快得多);而带有解决方案的 dash 5.7 eval
(不支持另一种)比带有解决方案的 ksh93 快一点"${@: -1}"
。因此,根据您的情况(脚本、交互式使用、对特定 shell 功能的支持等),做出选择...但请注意,在cp
(这将花费大部分时间)的上下文中,这些性能差异不会不引人注目。
我用于测试的脚本:
i=50000
while [ $i -ne 0 ];
do
# : "${@: -1}"
eval ': "${'"$#"'}"'
i=$((i-1))
done
(注释掉该eval
行并取消注释其他解决方案的前一行),调用方式为:
time sh ./tst `seq 1000`
time bash ./tst `seq 1000`
time ksh93 ./tst `seq 1000`
time zsh ./tst `seq 1000`
答案2
我有同样的问题并用来tar
解决它!就像这样:
tmpfile=/tmp/myfile.tar
files="/some/folder/file1.txt /some/other/folder/file2.txt"
targetfolder=/home/you/somefolder
tar --file="$tmpfile" "$files"
tar --extract --file="$tmpfile" --directory="$targetfolder"
在这种情况下,tar
将自动为您创建所有(子)文件夹!最好的,
彩蝶