当前位置:  开发笔记 > 运维 > 正文

如何使用xargs复制名称中包含空格和引号的文件?

如何解决《如何使用xargs复制名称中包含空格和引号的文件?》经验,为你挑选了11个好方法。

我正在尝试将一堆文件复制到目录下,并且许多文件的名称中都有空格和单引号.当我尝试串联findgrep使用时xargs,我收到以下错误:

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

有关更强大的xargs使用的任何建议?

这是在带有BSD的Mac OS X 10.5.3(Leopard)上xargs.



1> godbyk..:

您可以将所有这些组合到一个find命令中:

find . -iname "*foobar*" -exec cp -- "{}" ~/foo/bar \;

这将处理其中包含空格的文件名和目录.您可以使用它-name来获取区分大小写的结果.

注意:--传递的标志会cp阻止它处理以-as选项开头的文件.


人们使用xargs是因为通常每次使用200个参数调用可执行文件5次比每次使用一个参数调用1000次更快.
Chris Jester-Young的答案应该是那里的"好答案"......如果文件名以" - "开头,这个解决方案不起作用.至少,在cp之后需要" - ".
速度示例 - 超过829个文件,"find -exec"方法耗时26秒,而"find -print0 | xargs --null"方法工具耗时0.7秒.显着差异.
@tzot一个迟到的评论,但无论如何,`xargs`不需要解决你所描述的问题,`find`已经用`-exec`` +`标点符号支持它.
使用cp是可以的,但不是这样 - 以这种方式,为每个文件运行cp,因此为每个文件放置了fork + execve的非平凡开销.最好使用cp的-t选项.喜欢:`find .. -exec cp -t~/foo/bar - {} +`
没有回答如何处理空格的问题

2> Chris Jester..:

find . -print0 | grep --null 'FooBar' | xargs -0 ...

我不知道是否grep支持--null,是否也xargs支持-0,豹,但在GNU这一切都很好.


`find有什么问题.-name'FooBar'-print0 | xargs -0 ......`

3> 小智..:

做原始海报想要的最简单方法是将分隔符从任何空格更改为行尾字符,如下所示:

find whatever ... | xargs -d "\n" cp -t /var/tmp


这应该是公认的答案.问题是关于使用`xargs`.
很好的答案,但没有在Mac上工作.相反,我们可以将*find*传递给`sed -e'的_ \(.*\)_"\ 1"_g'`来强制引用文件名
这个anwser简单,有效,直截了当:为xargs设置的默认分隔符太宽,需要缩小OP想要做的事情.我知道这是第一手的,因为我今天碰到了类似的问题,除了在cygwin中.如果我阅读xargs命令的帮助,我可能已经避免了一些麻烦,但你的解决方案为我修复了它.谢谢 !(是的,OP在MacOS上使用BSD xargs,我没有使用,但我希望xargs"-d"参数存在于所有版本中).
我得到xargs:非法选项-d

4> Tometzky..:

这样更有效,因为它不会多次运行"cp":

find -name '*FooBar*' -print0 | xargs -0 cp -t ~/foo/bar


-p标志为cp是一个GNU扩展,AFAIK,并且在OS X上不可用.但如果是,它将如此答案所示.
我正在使用Linux。感谢您使用“ -t”开关。那就是我所缺少的:-)

5> oyouareatube..:

我遇到了同样的问题.这是我解决它的方式:

find . -name '*FoooBar*' | sed 's/.*/"&"/' | xargs cp ~/foo/bar

我曾经sed用相同的行替换每行输入,但用双引号括起来.在sed手册页中," ...替换中出现的&符号(``&'')被替换为匹配RE的字符串... " - 在这种情况下,.*整个行.

这解决了xargs: unterminated quote错误.


我在Windows上使用gnuwin32,所以我不得不使用`sed s /.*/\"&\"/来让它工作.

6> the_minted..:

此方法适用于Mac OS X v10.7.5(Lion):

find . | grep FooBar | xargs -I{} cp {} ~/foo/bar

我还测试了你发布的确切语法.这也适用于10.7.5.


这是有效的,但是`-I`意味着`-L 1`(所以说手册),这意味着每个文件运行一次cp命令= v slow.
对不起,但这是错的.首先,它产生了TO想要避免的错误.你必须使用`find ... -print0`和`xargs -0`来工作arround xargs的"默认报价是特殊的".其次,通常在传递给xargs的命令中使用`'{}'`not` {}`来防止空格和特殊字符.
对不起Andreas Spindler,我对xargs并不熟悉,经过一些实验后发现了这一行.它似乎适用于大多数评论过它并赞成它的人.您是否介意更详细地了解它产生的错误类型?另外,您是否介意发布您认为更正确的确切输入?谢谢.

7> jlliagre..:

只是不要使用xargs.这是一个简洁的计划,但find在面对非平凡的案件时,它并不顺利.

这是一个便携式(POSIX)解决方案,即不需要的解决方案find,xargscpGNU特定的扩展:

find . -name "*FooBar*" -exec sh -c 'cp -- "$@" ~/foo/bar' sh {} +

注意结尾+而不是更常见的结局;.

此解决方案:

正确处理带有嵌入空格,换行符或任何异域字符的文件和目录.

适用于任何Unix和Linux系统,甚至是那些不提供GNU工具包的系统.

不使用xargs哪个是一个很好的和有用的程序,但需要太多的调整和非标准功能来正确处理find输出.

也比接受的和大多数(如果不是全部)其他答案更有效(读取更快).

另请注意,尽管在其他一些回复或评论中说明引用{}是无用的(除非您使用异国情调的fish外壳).



8> Shannon Nels..:

在find中使用带有-print0选项的xargs的--null命令行选项.



9> Aleksandr Gu..:

对于那些依赖命令的人,除了查找,例如ls:

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



10> 小智..:

我发现以下语法对我很有用.

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".



11> mavit..:
find | perl -lne 'print quotemeta' | xargs ls -d

我相信这对于除换行之外的任何角色都能可靠地工作(我怀疑如果你的文件名中有换行符,那么你遇到的问题比这更糟).它不需要GNU findutils,只需要Perl,因此它应该可以在任何地方工作.


的确是.试试,例如,`mkdir test && cd test && perl -e'open $ fh,">","this-file-contains-a- \n-here"'&& ls | od -tx1`
推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有