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

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

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

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


当前回答

bill_starr的Perl版本不能很好地用于嵌入换行符(只处理空格)。对于那些没有GNU工具的Solaris,一个更完整的版本可能是(使用sed)…

find -type f | sed 's/./\\&/g' | xargs grep string_to_find

根据需要调整find和grep参数或其他命令,但sed将修复嵌入的换行符/空格/制表符。

其他回答

查看一下在xargs中使用——null命令行选项和find中的-print0选项。

如果系统上的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上测试

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

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

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

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

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

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

我发现下面的语法很适合我。

find /usr/pcapps/ -mount -type f -size +1000000c | perl -lpe ' s{ }{\\ }g ' | xargs ls -l | sort +4nr | head -200

在本例中,我正在查找挂载在“/usr/pcapps”的文件系统中最大的200个超过1,000,000字节的文件。

Perl在“find”和“xargs”之间的行- - -转义/引用每个空白,因此“xargs”将任何带有嵌入空白的文件名作为单个参数传递给“ls”。