如何从 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