我正在尝试将一堆文件复制到目录下,并且许多文件的名称中都有空格和单引号.当我尝试串联find
和grep
使用时xargs
,我收到以下错误:
find .|grep "FooBar"|xargs -I{} cp "{}" ~/foo/bar xargs: unterminated quote
有关更强大的xargs使用的任何建议?
这是在带有BSD的Mac OS X 10.5.3(Leopard)上xargs
.
您可以将所有这些组合到一个find
命令中:
find . -iname "*foobar*" -exec cp -- "{}" ~/foo/bar \;
这将处理其中包含空格的文件名和目录.您可以使用它-name
来获取区分大小写的结果.
注意:--
传递的标志会cp
阻止它处理以-
as选项开头的文件.
find . -print0 | grep --null 'FooBar' | xargs -0 ...
我不知道是否grep
支持--null
,是否也xargs
支持-0
,豹,但在GNU这一切都很好.
做原始海报想要的最简单方法是将分隔符从任何空格更改为行尾字符,如下所示:
find whatever ... | xargs -d "\n" cp -t /var/tmp
这样更有效,因为它不会多次运行"cp":
find -name '*FooBar*' -print0 | xargs -0 cp -t ~/foo/bar
我遇到了同样的问题.这是我解决它的方式:
find . -name '*FoooBar*' | sed 's/.*/"&"/' | xargs cp ~/foo/bar
我曾经sed
用相同的行替换每行输入,但用双引号括起来.在sed
手册页中," ...替换中出现的&符号(``&'')被替换为匹配RE的字符串... " - 在这种情况下,.*
整个行.
这解决了xargs: unterminated quote
错误.
此方法适用于Mac OS X v10.7.5(Lion):
find . | grep FooBar | xargs -I{} cp {} ~/foo/bar
我还测试了你发布的确切语法.这也适用于10.7.5.
只是不要使用xargs
.这是一个简洁的计划,但find
在面对非平凡的案件时,它并不顺利.
这是一个便携式(POSIX)解决方案,即不需要的解决方案find
,xargs
或cp
GNU特定的扩展:
find . -name "*FooBar*" -exec sh -c 'cp -- "$@" ~/foo/bar' sh {} +
注意结尾+
而不是更常见的结局;
.
此解决方案:
正确处理带有嵌入空格,换行符或任何异域字符的文件和目录.
适用于任何Unix和Linux系统,甚至是那些不提供GNU工具包的系统.
不使用xargs
哪个是一个很好的和有用的程序,但需要太多的调整和非标准功能来正确处理find
输出.
也比接受的和大多数(如果不是全部)其他答案更有效(读取更快).
另请注意,尽管在其他一些回复或评论中说明引用{}
是无用的(除非您使用异国情调的fish
外壳).
在find中使用带有-print0选项的xargs的--null命令行选项.
对于那些依赖命令的人,除了查找,例如ls
:
find . | grep "FooBar" | tr \\n \\0 | xargs -0 -I{} cp "{}" ~/foo/bar
我发现以下语法对我很有用.
find /usr/pcapps/ -mount -type f -size +1000000c | perl -lpe ' s{ }{\\ }g ' | xargs ls -l | sort +4nr | head -200
在这个例子中,我正在寻找安装在"/ usr/pcapps"的文件系统中超过1,000,000字节的最大200个文件.
"find"和"xargs"之间的Perl换行符转义/引用每个空格,因此"xargs"将任何带有嵌入空格的文件名作为单个参数传递给"ls".
find | perl -lne 'print quotemeta' | xargs ls -d
我相信这对于除换行之外的任何角色都能可靠地工作(我怀疑如果你的文件名中有换行符,那么你遇到的问题比这更糟).它不需要GNU findutils,只需要Perl,因此它应该可以在任何地方工作.