我已经通过以下命令将一些文件从一个用户帐户复制到一个新帐户
$ folders_array=(.mozilla .thunderbird .ssh .eclipse)
$ echo ${folders_array[@]} | xargs -d " " -I _ sudo cp -r _ /home/nebukadnexa/
我无法解释最后一个参数.eclipse
的形式,即它是'.eclipse'$'n'
,因此在我当前的主目录中找不到,因此当然也没有复制。
你能告诉我xargs是如何生成参数'.eclipse'$'n'
(最后一个参数(的吗?
编辑:也许比-d " "
更好的解决方案是tr " " "n"
?
echo ${folders_array[@]} | tr " " "n" | xargs -I _ printf "%sn" _
-d " "
时,echo
输出末尾的换行符被视为数据的一部分,而不是分隔符。
最简单的解决方法是不在一行上提供输入。(还要注意数组的固定报价。(
printf '%sn' "${folders_array[@]}" |
xargs -r sudo cp -t -r /home/nebukadnexa/
我还切换到cp -t
,它的存在正是为了简化这样的情况。这是一个GNU扩展,所以它不一定可以移植到非Linux平台(尽管编写自己的重新实现也不难(。
如果您需要支持完全任意的文件名(甚至是包含换行符的文件名(,那么printf '%s '
管道连接到xargs -0
是个不错的选择,不过这也是GNU扩展。
问题是,当您使用-I _
时,它会将_
替换为单个参数。POSIX指定了这个(强调矿(:
-Ireplstr
插入模式:对标准输入的每一行执行实用程序,将整行作为一个参数,每次出现replstr时将其插入参数中。
这就是GNUcp -t
扩展非常有用的原因。它允许您将要复制的文件放在命令末尾,默认情况下xargs
会将它们放在此处,而无需将它们合并为一个参数。
echo "${folders_array[@]}" | xargs sudo cp -r -t /home/nebukadnexa/
请注意,如果任何文件名包含空白,则到xargs
的管道将不起作用。
无论如何,我都不确定xargs
在这里的好处。
for d in .mozilla .thunderbird .ssh .eclipse
do sudo cp -r "$d" /home/nebukadnexa/
done