题
我怎么可以做xargs执行命令的一次对每个行输入定?这是默认行为是大块的线和执行命令的一次,通过多个行为每一个实例。
从 http://en.wikipedia.org/wiki/Xargs:
寻找路径型的f-print0|xargs-0rm
在这个例子中,找到馈送入xargs有一个长长的清单的文件名称。xargs然后分割这个名单成为子列表,并呼吁rm一次为每个子列表.这是更有效地比这一功能上等同的版本:
寻找路径型的f-exec rm'{}'\;
我知道,找到具有"执行"标志。我只是引用的一个说明性的例子,从其他资源。
解决方案
如果你没有在你的输入空间下才起作用:
xargs -L 1
xargs --max-lines=1 # synonym for the -L option
从人页:
-L max-lines
Use at most max-lines nonblank input lines per command line.
Trailing blanks cause an input line to be logically continued on
the next input line. Implies -x.
其他提示
在我看来,所有现有的答案在这个网页都是错误的,其中包括一个标明为正确的。这源自这一事实,问题是含糊的措辞。
摘要: 如果你想要执行的命令 "一次对每个线输给出的," 穿整个线(不在行)的命令作为 单参数, 然后这个是最好的UNIX兼容的方式做到这一点:
... | tr '\n' '\0' | xargs -0 -n1 ...
GNU xargs
可能或不可能拥有有用的扩展,能让你做掉 tr
, 但他们不是适用于OS X和其他UNIX系统。
现在长的解释...
有两个问题的时候要考虑到使用xargs:
- 它是如何拆分输入的"论点";和
- 许多参数通过的儿童的命令的时间。
测试xargs'的行为,我们需要一个实用工具,显示了多少次,它正在执行的和多少参数。我不知道是否有标准的实用做到这一点,但我们可以代码很容易在击:
#!/bin/bash
echo -n "-> "; for a in "$@"; do echo -n "\"$a\" "; done; echo
假设你保存它 show
在您目前的目录,并使其可执行的,这里是它是如何工作:
$ ./show one two 'three and four'
-> "one" "two" "three and four"
现在,如果原来的问题是关于第2点上述(作为我认为它是,在阅读了几次在),它是被读取这样的(变化的大胆):
我怎么可以做xargs执行该命令正是每一次 参数 入定?它的默认行为是大块的 输入参数 和执行命令 尽可能少的时间, ,通过多 参数 每个实例。
那么答案是 -n 1
.
让我们比较xargs'默认行为,拆分输入周围的空白,并呼吁该命令尽可能少的时间:
$ echo one two 'three and four' | xargs ./show
-> "one" "two" "three" "and" "four"
和行为 -n 1
:
$ echo one two 'three and four' | xargs -n 1 ./show
-> "one"
-> "two"
-> "three"
-> "and"
-> "four"
如果,另一方面,原来的问题是关于第1点.输入的分裂,它是被读取这样的(许多人来到这里似乎认为这种情况下,或是混淆这两个问题):
我怎么可以做xargs执行命令 与 到底 一个参数 为每个行输入定?它的默认行为是大块线 周围的空白.
那么答案是更加微妙。
人们会认为 -L 1
可能的帮助,但事实证明,这并没有改变的参数分析。它只是执行命令一旦每个输线,许多论点是没有上那输入线:
$ echo $'one\ntwo\nthree and four' | xargs -L 1 ./show
-> "one"
-> "two"
-> "three" "and" "four"
不仅如此,但是,如果一条线结束与空白,它所附的下一步:
$ echo $'one \ntwo\nthree and four' | xargs -L 1 ./show
-> "one" "two"
-> "three" "and" "four"
显然, -L
不是关于改变方式xargs分裂的输入参数。
唯一的参数,这样做在一个跨平台的方式(不包括GNU扩展)是 -0
, ,拆分输入周围NUL字节。
然后,它只是把新行为NUL的帮助 tr
:
$ echo $'one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 ./show
-> "one " "two" "three and four"
现在的参数的分析看起来所有的权利,包括追踪空白。
最后,如果你把这种技术 -n 1
, 你得到确切的一个命令的执行每次输入线,无论输入你有,这可能是又一个方式来看待在最初的问题(可能是最直观的,鉴于标题):
$ echo $'one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 -n1 ./show
-> "one "
-> "two"
-> "three and four"
如果你想要跑的命令 每 线(即结果)来自 find
, 然后你需要什么的 xargs
用的?
尝试:
find
路径 -type f -exec
你的命令 {} \;
那里的文字 {}
被取代通过的文件和文字的 \;
需要 find
要知道,该定义命令结束在那里。
编辑:
(后的编辑问题的澄清,你知道 -exec
)
从 man xargs
:
-L max-行
使用最多 max-行 非空输入线每命令行。后 空白的原因输入线以逻辑地继续在下一个输入线。意味着-x。
注意,文件名止在空白,将会导致你的麻烦,如果你使用 xargs
:
$ mkdir /tmp/bax; cd /tmp/bax
$ touch a\ b c\ c
$ find . -type f -print | xargs -L1 wc -l
0 ./c
0 ./c
0 total
0 ./b
wc: ./a: No such file or directory
所以如果你不关心 -exec
选择你最好用 -print0
和 -0
:
$ find . -type f -print0 | xargs -0L1 wc -l
0 ./c
0 ./c
0 ./b
0 ./a
我怎样才能使xargs的对于给定的输入的每一行执行命令恰好一次?
我不使用-L 1
答案,因为它不处理带空格的文件是find -print0
的关键功能。
echo "file with space.txt" | xargs -L 1 ls
ls: file: No such file or directory
ls: space.txt: No such file or directory
ls: with: No such file or directory
一个更好的解决方案是使用tr
转换换行符为空(\0
)字符,然后使用xargs -0
参数。
echo "file with space.txt" | tr '\n' '\0' | xargs -0 ls
file with space.txt
如果你这时就需要限制呼叫的数量,你可以使用-n 1
争论使一个调用程序为每个输入:
echo "file with space.txt" | tr '\n' '\0' | xargs -0 -n 1 ls
这也可以让你筛选发现的输出的前的转换断裂成空。
find . -name \*.xml | grep -v /workspace/ | tr '\n' '\0' | xargs -0 tar -cf xml.tar
另一备选...
find /path -type f | while read ln; do echo "processing $ln"; done
find path -type f | xargs -L1 command
是你所需要的。
这两种方式也行,并为未使用找到其他命令的工作!
xargs -I '{}' rm '{}'
xargs -i rm '{}'
示例使用情形:
find . -name "*.pyc" | xargs -i rm '{}
将删除这个目录即使PYC文件包含空格下的所有文件PYC
下面的命令会发现在/path
的所有文件(型的F),然后使用cp
到当前文件夹复制它们。注意,使用如果-I %
指定在cp
命令行一个占位符,使得参数可以被放置在文件名之后。
find /path -type f -print0 | xargs -0 -I % cp % .
与xargs的(GNU的findutils)测试4.4.0
可以使用--max线或--max-ARGS标志,分别限制线,或参数的数目(如果存在每个参数之间的空间)。
-L max-lines Use at most max-lines nonblank input lines per command line. Trailing blanks cause an input line to be logically continued on the next input line. Implies -x. --max-lines[=max-lines], -l[max-lines] Synonym for the -L option. Unlike -L, the max-lines argument is optional. If max-args is not specified, it defaults to one. The -l option is deprecated since the POSIX standard specifies -L instead. --max-args=max-args, -n max-args Use at most max-args arguments per command line. Fewer than max-args arguments will be used if the size (see the -s option) is exceeded, unless the -x option is given, in which case xargs will exit.
看来我没有足够的声誉添加评论,托比亚的回答以上,所以我加入这个“答案”,以帮助那些我们想用在Windows平台xargs
以同样的方式进行试验。
下面是做同样的事情托比亚的快速编码“秀”脚本Windows批处理文件:
@echo off
REM
REM cool trick of using "set" to echo without new line
REM (from: http://www.psteiner.com/2012/05/windows-batch-echo-without-new-line.html)
REM
if "%~1" == "" (
exit /b
)
<nul set /p=Args: "%~1"
shift
:start
if not "%~1" == "" (
<nul set /p=, "%~1"
shift
goto start
)
echo.
@Draemon答案似乎是正确的用“-0”,即使文件中的空间。
我试图xargs命令,我发现“-0”与“-L”完美的作品。甚至空格被处理(如果输入是空终止)。以下是一个例子:
#touch "file with space"
#touch "file1"
#touch "file2"
下面将分割空值和在所述列表中的每个参数执行命令:
#find . -name 'file*' -print0 | xargs -0 -L1
./file with space
./file1
./file2
所以-L1
将执行在每个空终止字符的参数,如果使用具有“-0”。看出差别尝试:
#find . -name 'file*' -print0 | xargs -0 | xargs -L1
./file with space ./file1 ./file2
即使这样也执行一次:
#find . -name 'file*' -print0 | xargs -0 | xargs -0 -L1
./file with space ./file1 ./file2
该命令将作为“-L”现在不能在空字节划分一次执行。你必须同时提供“-0”和“-L”工作。
在您的例子中,找到的输出管道,以xargs的的一点是,发现的-exec选项的标准行为是一次为每个找到的文件执行的命令。如果您使用的发现,并希望其标准的行为,那么答案很简单 - 不使用xargs的开始与
执行蚂蚁任务清除所有关于当前或子文件夹中的每个的build.xml。
find . -name 'build.xml' -exec ant -f {} clean-all \;