统计终端输出中的行数

362

在SO上找不到相关内容。我在终端中运行了以下命令:

>> grep -Rl "curl" ./

这将显示包含关键字curl的文件列表。我想要计算文件数。我能想到的第一种方法是计算终端输出中的行数。如何实现?


51
grep本身也有-c标志,它只返回计数。 - EaterOfCode
相关内容:https://unix.stackexchange.com/questions/248245/how-to-count-the-number-of-lines-of-an-output - AlikElzin-kilaka
如果需要递归搜索/计数,请使用以下命令:grep -Ric "searchpattern" ./ - Karthik Rao
5个回答

637

使用-l行数)开关将结果管道传输到 wc

grep -Rl "curl" ./ | wc -l

6
我一直在使用 grep "" -c,但这个方法更好看 :) - ninhenzo64
7
值得注意的是,将内容管道传输给wc命令的这个技巧适用于任何输出,而不仅仅是grep的输出。例如,它可以与git diff命令结合使用。 - Jason L.
1
为什么这是被接受的答案?正如一些评论所提到的,应该使用内置函数grep -c而不是将输出导入到另一个程序中。例如,您甚至不会使用Word以外的文本编辑器更改Word文档中的字符,对吧? - Michael P
4
这个答案被接受是因为问题通常要求如何计算终端输出的行数。grep -c不能回答这个问题。 - Dave C

65

将EaterOfCode的评论放在这里作为回答。

grep本身也有-c标志,它只返回计数。

因此,命令和输出可能如下所示。

$ grep -Rl "curl" ./ -c
24

编辑:

尽管这个回答可能更短,看起来比被接受的答案(使用wc)更好。但我不再同意这一观点。我认为记住可以通过管道输入wc -l来计算行数要更有用,因为您也可以将其与其他程序一起使用而不仅仅是grep


20

如果最后一行以换行符结尾,使用管道到 'wc' 更好(我知道在这种情况下,它会是这样)
但是,如果最后一行没有以换行符结尾,则 'wc -l' 将返回错误的结果。

例如:

$ echo "asd" | wc -l

将返回1

$ echo -n "asd" | wc -l

将返回0


所以我经常使用的是grep <anything> -c

$ echo "asd" | grep "^.*$" -c
1

$ echo -n "asd" | grep "^.*$" -c
1

这比wc -l返回的结果更接近实际情况。


1
wc -l 的输出开头有一个制表符会有问题吗? - theonlygusti
如果使用 wc -l 命令时没有行数而只有换行符,你也会得到错误的计数;建议使用带有 -c 选项的 grep 命令。 - undefined

3

"abcd4yyyy" | grep 4 -c 统计结果为 1


2
不清楚这个补充有什么意义,其他答案在近6年前已经更好地表达了。 - underscore_d

0
在我找到的之前的答案中,有一个情况没有被考虑到。
当尝试计算输出中打印的可视行数时,仅使用wc -l是不够的,因为它没有考虑到换行。
例如,在下面的示例中,你可以看到打印了1行。但是因为窗口非常小,输出占据了3行。

enter image description here

这在尝试移除先前的输出并用新的覆盖时非常有用。
对于这种情况,我在这里找到了一个解决方案:https://stackoverflow.com/a/29996354/5150227 原始解决方案存在一些错误。因此,最终结果将如下所示:
# Lines being printed
printf "%s" "$TAIL_BUFFER"

seenlines=0
cols=$( tput cols )
while IFS= read -r line; do
  # Remove non-printable characters from the line
  lineOfPrintedCharacters=$(echo "$line" | tr -dc '[[:print:]]')

  # Get length of the line in characters,
  # subtracting the newline:
  newLength=$(( $( wc -m <<< "$lineOfPrintedCharacters" ) - 1 ))

  # Add at least one line, and one for each time the line length 
  # exceeds the column size of the terminal
  seenlines=$( bc <<< "$seenlines + 1 + ${newLength} / ${cols}" )

  # Do not remove lines that finish exactly at the edge of the terminal
  if [[ $(( (${newLength}) % ${cols} )) -eq 0 ]] && [[ $newLength -ne 0 ]]; then
    seenlines=$((seenlines - 1))
  fi
done <<< "$TAIL_BUFFER"

echo "${seenlines} lines seen"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接