将输出行数分配给变量

将输出行数分配给变量

如何从 bash 脚本运行命令并在最后打印它打印的行数?

awk 等效项是

{ print; } 
END { print NR; }

我只能想出以下内容。目前这有效,但我无法在子外壳之外获取它。

| (lc=0; while read; do echo $REPLY; lc=$(($lc+1)); done; echo $lc)

更新

看来我的问题完全不同。我首先尝试使用/dev/stdout失败:

tester> { echo abc | tee /dev/stdout | wc -l;  } > /tmp/abc; cat /tmp/abc
2

这似乎是因为tee /dev/stdout给出了错误:

tester> echo abc | tee /dev/stdout
tee: /dev/stdout: Permission denied
abc

回答杰夫·夏勒 (Jeff Schaller) 的作品:

tester> { echo abc | tee >(wc -l);  } > /tmp/abc; cat /tmp/abc
abc
1

但今天早上重试时我发现它有效!

tmp> echo abc | tee /dev/stdout
abc
abc

经过一段时间的研究,我发现了两个问题:

昨天失败时|tee /dev/stdout,我以 usr1 身份登录,对另一个 usr2 执行了 sudo sudo su usr2,。在这种情况下,软链接的链是/dev/stdout -> /proc/self/fd/1 -> /dev/pts/1,最后一个链接的所有者是usr1。所以tee失败了。今天我以usr1身份尝试了一下,果然成功了。

但后来我意识到 的另一个错误tee /dev/stdout,即所有输出都转到wc -l;行数是双倍并且没有打印任何内容。

答案1

我不确定如何更好地打印行数:

$ seq 1 5 2>&1 | tee >(wc -l | { read lines; echo Lines of output: $lines; })
1
2
3
4
5
$ Lines of output: 5

这会将命令的(此处seq 1 5)stderr 重定向到 stdout,以便tee看到这两个流;然后 tee 将其输入复制回来,并将输入复制到运行wc -l以计算行数的进程替换中。然后,我将 的输出读wc$lines变量以提供报告。

答案2

使用sed

some_command | sed -n 'p;$='

例如:

$ touch file.{a..k}
$ printf '%s\n' * | sed -n 'p;$='
file.a
file.b
file.c
file.d
file.e
file.f
file.g
file.h
file.i
file.j
file.k
11

sed脚本只会将输入复制到输出,并将打印命令 ( p) 应用于输入的每一行,但对于最后一行 ( $),它还会打印行号 ( =)。

答案3

您可以简单地使用 awk 命令:

echo -e "foo\nbar"| awk '{ 打印; }END { 打印 NR; }'
酒吧
2

相关内容