如何使xargs对给定的每一行输入执行一次命令? 它的默认行为是将行分块并执行一次命令,将多行传递给每个实例。

从http://en.wikipedia.org/wiki/Xargs: 查找/path -type f -print0 | xargs -0 rm 在本例中,find为xargs的输入提供一长串文件名。然后Xargs将这个列表拆分为子列表,并对每个子列表调用rm一次。这比功能等效的版本更有效: 查找/path -type f -exec rm '{}' \;

我知道那个发现有"执行"的标志。我只是从另一种资源中引用了一个说明性的例子。


当前回答

另一种选择……

find /path -type f | while read ln; do echo "processing $ln"; done

其他回答

似乎我没有足够的声望对上面的Tobia的回答添加评论,所以我添加这个“答案”是为了帮助那些希望在Windows平台上以同样的方式试验xargs的人。

下面是一个windows批处理文件,它做的事情与Tobia快速编码的“show”脚本相同:

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

另一种选择……

find /path -type f | while read ln; do echo "processing $ln"; done

您可以分别使用——max-lines或——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.

这两种方法也可以工作,并将适用于其他没有使用find!

xargs -I '{}' rm '{}'
xargs -i rm '{}'

示例用例:

find . -name "*.pyc" | xargs -i rm '{}'

将删除此目录下的所有pyc文件,即使pyc文件包含空格。

@Draemon的答案似乎是正确的“-0”,即使在文件中有空格。

我正在尝试xargs命令,我发现“-0”与“-L”完美地工作。即使空格也会被处理(如果输入以空结尾)。举例如下:

#touch "file with space"
#touch "file1"
#touch "file2"

下面的代码将拆分null值,并对列表中的每个参数执行命令:

 #find . -name 'file*' -print0 | xargs -0 -L1
./file with space
./file1
./file2

因此-L1将对每个以null结尾的字符执行参数,如果使用"-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”才能工作。