xargs wc -l 报告两个总数
xargs wc -l reports two totals
我要计算目录/usr/local/lib/python3.5/dist-packages/pandas
.
中的所有行
cd /usr/local/lib/python3.5/dist-packages/pandas
find -name '*.*' |xargs wc -l
536577 total
将两行写成一行。
find /usr/local/lib/python3.5/dist-packages/pandas -name '*.*' |xargs wc -l
bash输出两个total
数,一个是495736
,一个是40841
,
495736 + 40841 = 536577
为什么bash只给一个总536577
在最下面如find -name '*.*' |xargs wc -l
呢?
The generated command line length shall be the sum of the size in bytes of the utility name and each argument treated as strings, including a null byte terminator for each of these strings. The xargs utility shall limit the command line length such that when the command line is invoked, the combined argument and environment lists shall not exceed {ARG_MAX}-2048
bytes.
这意味着;在您的情况下,find 的输出不适合 ARG_MAX‒2048 字节,因此 xargs 将其聚合为 2 组并为每组调用 wc 一次。
以这条管道为例,在理想世界中它的输出应该是 1,但事实并非如此。
seq 1000000 | xargs echo | wc -l
seq 的输出是 6888896 字节。
$ seq 1000000 | wc -c
6888896
我的环境列表占用558个字节(忽略_
是动态的,为了清楚起见,实现是否考虑了终止空指针)。
$ env | wc -c
558
ARG_MAX
在我的系统上是 131072 字节。
$ getconf ARG_MAX
131072
现在 xargs 有 131072-2048-558 = 128466 字节; echo
加上空分隔符占用5个字节,所以还剩下一个space,共128461字节。因此我们可以说,xargs 将不得不调用 echo
6888896/128461 = ~54 次。让我们看看是不是这样:
$ seq 1000000 | xargs echo | wc -l
54
是的,是的。
您可以通过向管道添加 awk
位来多次处理 xargs
运行 命令:
find wherever -name "*.*" -type f -print0 | \
xargs -0 wc -l | \
awk ' == "total" { total += } END { print "Overall total", total } 1'
(假设 GNU find
和 xargs
或其他分别理解 -print0
和 -0
的实现;否则文件名中包含空格等可能会导致问题)。
GNU find
也许其他实现可以跳过 xargs
,实际上:
find wherever -name "*.*" -type f -exec wc -l '{}' '+'
与一次对多个文件使用 xargs
到 运行 wc
的效果相同。
我要计算目录/usr/local/lib/python3.5/dist-packages/pandas
.
cd /usr/local/lib/python3.5/dist-packages/pandas
find -name '*.*' |xargs wc -l
536577 total
将两行写成一行。
find /usr/local/lib/python3.5/dist-packages/pandas -name '*.*' |xargs wc -l
bash输出两个total
数,一个是495736
,一个是40841
,
495736 + 40841 = 536577
为什么bash只给一个总536577
在最下面如find -name '*.*' |xargs wc -l
呢?
The generated command line length shall be the sum of the size in bytes of the utility name and each argument treated as strings, including a null byte terminator for each of these strings. The xargs utility shall limit the command line length such that when the command line is invoked, the combined argument and environment lists shall not exceed
{ARG_MAX}-2048
bytes.
这意味着;在您的情况下,find 的输出不适合 ARG_MAX‒2048 字节,因此 xargs 将其聚合为 2 组并为每组调用 wc 一次。
以这条管道为例,在理想世界中它的输出应该是 1,但事实并非如此。
seq 1000000 | xargs echo | wc -l
seq 的输出是 6888896 字节。
$ seq 1000000 | wc -c
6888896
我的环境列表占用558个字节(忽略_
是动态的,为了清楚起见,实现是否考虑了终止空指针)。
$ env | wc -c
558
ARG_MAX
在我的系统上是 131072 字节。
$ getconf ARG_MAX
131072
现在 xargs 有 131072-2048-558 = 128466 字节; echo
加上空分隔符占用5个字节,所以还剩下一个space,共128461字节。因此我们可以说,xargs 将不得不调用 echo
6888896/128461 = ~54 次。让我们看看是不是这样:
$ seq 1000000 | xargs echo | wc -l
54
是的,是的。
您可以通过向管道添加 awk
位来多次处理 xargs
运行 命令:
find wherever -name "*.*" -type f -print0 | \
xargs -0 wc -l | \
awk ' == "total" { total += } END { print "Overall total", total } 1'
(假设 GNU find
和 xargs
或其他分别理解 -print0
和 -0
的实现;否则文件名中包含空格等可能会导致问题)。
GNU find
也许其他实现可以跳过 xargs
,实际上:
find wherever -name "*.*" -type f -exec wc -l '{}' '+'
与一次对多个文件使用 xargs
到 运行 wc
的效果相同。