find
的每条
我如何使xargs对给定的每一行输入仅执行一次命令?它的默认行为是对行进行分块并执行一次,将多行传递给每个实例。
来自http://en.wikipedia.org/wiki/Xargs:
找到/ path -type f -print0 | xargs -0 rm
在此示例中,find为xargs的输入提供了很长的文件名列表。然后,xargs将此列表拆分为子列表,并为每个子列表调用rm一次。这比功能上等效的版本更有效:
找到/ path -type f -exec rm'{}'\;
我知道查找具有“ exec”标志。我只是引用另一个资源中的说明性示例。
以下内容仅在输入中没有空格时有效:
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.
xargs
的我们这些人。这里是Windows批处理文件,与Tobia快速编码的“显示”脚本具有相同的作用:
我正在尝试xargs命令,但发现“ -0”与“ -L”完美配合。即使空格也被处理(如果输入为null终止)。以下是一个示例:
find . -name 'build.xml' -exec ant -f {} clean-all \;
在我看来,此页面上所有现有的答案都是错误的,包括标记为正确的答案。这是因为问题的措词含糊。
摘要:如果要执行命令“对于给定的每一行输入仅执行一次,”将整个行(不带换行符)作为单个参数,]传递给命令>那么这是最佳的UNIX兼容方法:
... | tr '\n' '\0' | xargs -0 -n1 ...
GNU
xargs
可能有也可能没有有用的扩展名,这些扩展名可以使您不再使用tr
,但是在OS X和其他UNIX系统上不可用。
现在进行详细说明...
使用xargs时要考虑两个问题:
为了测试xargs的行为,我们需要一个实用程序,该实用程序可以显示它执行了多少次以及带有多少个参数。我不知道是否有标准实用程序可以执行此操作,但是我们可以在bash中很容易地对其进行编码:
#!/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精确执行一次命令?它的默认行为是对输入到参数
进行分块并执行尽可能少的次数,将多个arguments传递给每个实例。那么答案是-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点。输入拆分,则应这样阅读(许多来这里的人似乎认为是这种情况,或者使这两个问题混淆了:]一个参数?它的默认行为是对行around whitespace。进行分块。那么答案就更微妙了。对于给定的每一行输入,我如何使xargs准确地执行命令with
[有人认为-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个字节。
然后,只需在tr
的帮助下将换行符转换为NUL:
$ 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-lines个非空白输入行。尾随空白导致输入行在逻辑上在下一条输入行上继续。表示-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: with: No such file or directory ls: space.txt: 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
这还允许您过滤findbefore
的输出,将中断转换为null。find . -name \*.xml | grep -v /target/ | 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测试
-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.
[我似乎没有足够的声誉在Tobia's answer above上添加评论,所以我添加此“答案”来帮助希望在Windows平台上以相同方式尝试xargs
的我们这些人。这里是Windows批处理文件,与Tobia快速编码的“显示”脚本具有相同的作用:
@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”完美配合。即使空格也被处理(如果输入为null终止)。以下是一个示例:
#touch "file with space" #touch "file1" #touch "file2"
以下内容将拆分空值,并对列表中的每个参数执行命令:
#find . -name 'file*' -print0 | xargs -0 -L1 ./file with space ./file1 ./file2
因此-L1
如果与“ -0”一起使用,将在每个以null结尾的字符上执行参数。要查看差异,请尝试:
#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”才能正常工作。在您的示例中,将find的输出传递给xargs的一点是,find的-exec选项的标准行为是对每个找到的文件执行一次命令。如果您使用的是find,并且想要它的标准行为,那么答案很简单-请勿使用xargs开头。在当前或子文件夹中的每个build.xml上执行ant任务全清理。
find . -name 'build.xml' -exec ant -f {} clean-all \;
find
的每条
如何使xargs对给定的每一行输入执行一次命令?
find path -type f | xargs -L1 command
/path
中找到所有文件(-f型),然后使用cp
将它们复制到当前文件夹。注意,如果-I %
在cp
命令行中指定占位符,则可以在文件名之后放置参数。find /path -type f -print0 | xargs -0 -I % cp % .
-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.