如何在xargs -0之后执行多个命令?
find . -name "filename including space" -print0 | xargs -0 ls -aldF > log.txt
find . -name "filename including space" -print0 | xargs -0 rm -rdf
是否可以将这两个命令合并为一个,以便只完成 1 个查找而不是 2 个查找?
我知道 xargs -I 可能有多种方法可以做到这一点,这可能会导致在处理包含空格的文件名时出现错误。非常感谢任何指导。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
刚才遇到了这个问题,我们可以减少调用 shell 的频率:
结尾的“sh”在 shell 中变成 $0。
xargs
将文件(从find
返回)作为命令行参数提供给 shell:我们使用 for 循环迭代它们。Ran across this just now, and we can invoke the shell less often:
The trailing "sh" becomes $0 in the shell.
xargs
provides the files (returrned fromfind
) as command line parameters to the shell: we iterate over them with the for loop.如果您只是想避免多次执行
find
,则可以在find
之后立即执行tee
,从而保存find
输出到文件,然后执行以下行:完成同一件事的另一种方法(如果确实是您想要完成的事情)是存储
find
的输出> 在一个变量中(假设它不是TB 数据):If you're just wanting to avoid doing the
find
multiple times, you could do atee
right after thefind
, saving thefind
output to a file, then executing the lines as:Another way to accomplish this same thing (if indeed it's what you're wanting to accomplish), is to store the output of the
find
in a variable (supposing it's not TB of data):我相信现在所有的答案都给出了解决这个问题的正确方法。我尝试了 Jonathan 的两种解决方案和 Glenn 的方法,所有这些方法在我的 Mac OS X 上都效果很好。 mouviciel 的方法在我的操作系统上不起作用,可能是由于某些配置原因。我认为这与乔纳森的第二种方法类似(我可能是错的)。
正如格伦方法的评论中提到的,需要进行一些调整。所以这是我尝试过的命令,它运行得非常好,仅供参考:
或者按照格伦的建议更好:
I believe all these answers by now have given out the right ways to solute this problem. And I tried the 2 solutions of Jonathan and the way of Glenn, all of which worked great on my Mac OS X. The method of mouviciel did not work on my OS maybe due to some configuration reasons. And I think it's similar to Jonathan's second method (I may be wrong).
As mentioned in the comments to Glenn's method, a little tweak is needed. So here is the command I tried which worked perfectly FYI:
Or better as suggested by Glenn:
只要文件名中没有换行符,GNU Parallel 就不需要 -print0:
观看介绍视频以了解更多信息:http://www.youtube.com/watch?v=OpaiGYxkSuQ
As long as you do not have newline in your filenames, you do not need -print0 for GNU Parallel:
Watch the intro video to learn more: http://www.youtube.com/watch?v=OpaiGYxkSuQ
只是
xargs
方法的一种变体,没有可怕的-print0
和xargs -0
,这就是我的做法:脚注:
xargs
有简短的选项,但为了读者的理解,我使用了较长的选项。Just a variation of the
xargs
approach without that horrible-print0
andxargs -0
, this is how I would do it:Footnotes:
xargs
but for the reader's understanding I've used the long ones.ls -1
when I want non-recursive behavior rather thanfind -maxdepth 1 -iname "*.txt"
which is a bit more verbose.您可以在
find
之后使用for
而不是xargs
执行多个命令:IFS
定义内部字段分隔符,它默认为<空格><制表符><换行>。如果您的文件名可能包含空格,最好按照上面的方法重新定义它。You can execute multiple commands after
find
usingfor
instead ofxargs
:The
IFS
defines the Internal Field Separator, which defaults to <space><tab><newline>. If your filenames may contain spaces, it is better to redefine it as above.我迟到了,但这里没有介绍另一种解决方案:用户定义的函数。将多条指令放在一行上很不方便,并且难以阅读/维护。上面的 for 循环避免了这种情况,但有可能超出命令行长度。
这是另一种方法(未经测试)。
除了“dummyArg”之外,这非常简单,它给了我很多悲伤。以这种方式运行 bash 时,会读取参数
而不是预期的
参数由于 processFiles{} 期望第一个参数为“$1”,因此我们必须在“”中插入一个虚拟值0 美元”。
Footnontes:
除了风格问题之外,当“find”命令不返回任何内容时,它就会中断。在这种情况下,$0 设置为“bash”,使用虚拟参数可以避免所有这些。
I'm late to the party, but there is one more solution that wasn't covered here: user-defined functions. Putting multiple instructions on one line is unwieldy, and can be hard to read/maintain. The for loop above avoids that, but there is the possibility of exceeding the command line length.
Here's another way (untested).
This is pretty straightforward except for the "dummyArg" which gave me plenty of grief. When running bash in this way, the arguments are read into
instead of the expected
Since processFiles{} is expecting the first argument to be "$1", we have to insert a dummy value into "$0".
Footnontes:
Aside from stylistic issues, it breaks when the "find" command returns nothing. In that case, $0 is set to "bash", Using the dummy argument instead avoids all of this.
另一个解决方案:
Another solution: