我试图复制一堆文件下面的目录和一些文件有空格和单引号在他们的名字。当我尝试用xargs将find和grep串在一起时,我得到以下错误:

find .|grep "FooBar"|xargs -I{} cp "{}" ~/foo/bar
xargs: unterminated quote

对于更健壮地使用xargs有什么建议吗?

这是在Mac OS X 10.5.3 (Leopard)上使用BSD xargs。


当前回答

如果系统上的find和xarg版本不支持-print0和-0开关(例如AIX find和xargs),您可以使用以下看起来很糟糕的代码:

 find . -name "*foo*" | sed -e "s/'/\\\'/g" -e 's/"/\\"/g' -e 's/ /\\ /g' | xargs cp /your/dest

这里sed将负责转义xargs的空格和引号。

在AIX 5.3上测试

其他回答

请注意,其他答案中讨论的大多数选项在不使用GNU实用程序的平台上都不是标准的(例如Solaris、AIX、HP-UX)。关于“标准”xargs行为,请参阅POSIX规范。

我还发现xargs的行为,即它至少运行一次命令,即使没有输入,这是一个麻烦。

我写了我自己的xargs (xargl)的私人版本来处理名称中的空格问题(只有换行符分开-尽管'find…-print0'和'xargs -0'的组合非常简洁,因为文件名不能包含ASCII NUL '\0'字符。我的xargl还没有完整到值得发布的程度——特别是因为GNU的工具至少和它一样好。

找到。-print0 | grep——null 'FooBar' | xargs -0…

我不知道grep是否支持-null,也不知道xargs是否支持-0,在Leopard上,但在GNU上都很好。

我使用了Bill Star在Solaris上稍作修改的回答:

find . -mtime +2 | perl -pe 's{^}{\"};s{$}{\"}' > ~/output.file

这将在每行周围加上引号。我没有使用“-l”选项,尽管它可能会有所帮助。

我要去的文件列表可能有'-',但没有换行符。我没有使用输出文件与任何其他命令,因为我想回顾什么是发现之前,我只是开始大规模删除他们通过xargs。

对于那些依赖命令,而不是find,例如ls:

find . | grep "FooBar" | tr \\n \\0 | xargs -0 -I{} cp "{}" ~/foo/bar

你可能需要像这样grep Foobar目录:

find . -name "file.ext"| grep "FooBar" | xargs -i cp -p "{}" .