【问题标题】:wc -l is NOT counting last of the file if it does not have end of line characterwc -l 如果没有行尾字符,则不计算文件的最后一个
【发布时间】:2015-01-20 05:53:45
【问题描述】:

我需要计算一个 unix 文件的所有行。该文件有 3 行,但 wc -l 只给出 2 个计数。

我知道它不计算最后一行,因为它没有行尾字符

谁能告诉我如何计算那条线?

【问题讨论】:

标签: linux bash shell unix


【解决方案1】:

grep -c 返回匹配的行数。只需使用空字符串"" 作为匹配表达式:

$ echo -n $'a\nb\nc' > 2or3.txt
$ cat 2or3.txt | wc -l
2
$ grep -c "" 2or3.txt
3

【讨论】:

  • 即使没有-F 标志,grep 解决方案也比最小的awksed 版本更快,并且非常接近wc -l 本身。
  • rg --fixed-strings --count '' for ripgrep
【解决方案2】:

无论文件中的最后一行是否以换行符结尾,这种方法都会给出正确的行数。

awk 将确保在其输出中,它打印的每一行都以换行符结尾。因此,在将行发送到wc 之前,要确保每一行都以换行符结尾,请使用:

awk '1' file | wc -l

在这里,我们使用了简单的awk 程序,它仅由数字1 组成。 awk 将这个神秘的语句解释为它所做的“打印行”,确保存在尾随换行符。

示例

让我们创建一个包含三行的文件,每行以换行符结尾,并计算行数:

$ echo -n $'a\nb\nc\n' >file
$ awk '1' f | wc -l
3

找到正确的号码。

现在,让我们在缺少最后一个新行的情况下再试一次:

$ echo -n $'a\nb\nc' >file
$ awk '1' f | wc -l
3

这仍然提供正确的数字。 awk 自动更正缺少的换行符,但如果最后一个换行符存在,则保留文件。

【讨论】:

  • 这是最好的答案,因为它不需要修改文件,如果不需要也不会更改计数。
【解决方案3】:

最好在 Unix 文件中所有行都以 EOL \n 结尾。你可以这样做:

{ cat file; echo ''; } | wc -l

或者这个 awk:

awk 'END{print NR}' file

【讨论】:

  • 您可以随时在本地文件系统上执行echo -n '' >> file
  • 另一种计算方式是:{ cat file; echo ''; } | wc -l
  • 甚至awk 'END{print NR}' file
  • { cat file; echo ''; } | wc -l 正在工作。谢谢;你能重新发布答案吗?这样我就接受了!
  • @logan:请注意,如果文件已经以 \n 结尾,{ cat file; echo ''; } | wc -l 将给出错误答案,因为它总是添加了一个额外的行,所以 awk基于-的解决方案更好。
【解决方案4】:

尊重

我尊重answer from John1024 并希望对其进行扩展。

行计数功能

我发现自己比较了很多行数,尤其是来自剪贴板的行数,所以我定义了一个 bash 函数。我想修改它以显示文件名,并且当总共传递超过 1 个文件时。但是,到目前为止,这对我来说还不够重要。

# semicolons used because this is a condensed to 1 line in my ~/.bash_profile
function wcl(){
  if [[ -z "${1:-}" ]]; then
    set -- /dev/stdin "$@";
  fi;
  for f in "$@"; do
    awk 1 "$f" | wc -l;
  done;
}

不使用函数计算行数

# Line count of the file
$ cat file_with_newline    | wc -l
       3

# Line count of the file
$ cat file_without_newline | wc -l
       2

# Line count of the file unchanged by cat
$ cat file_without_newline | cat | wc -l
       2

# Line count of the file changed by awk
$ cat file_without_newline | awk 1 | wc -l
       3

# Line count of the file changed by only the first call to awk
$ cat file_without_newline | awk 1 | awk 1 | awk 1 | wc -l
       3

# Line count of the file unchanged by awk because it ends with a newline character
$ cat file_with_newline    | awk 1 | awk 1 | awk 1 | wc -l
       3

计数字符(为什么你不想在 wc 周围加上包装器)

# Character count of the file
$ cat file_with_newline    | wc -c
       6

# Character count of the file unchanged by awk because it ends with a newline character
$ cat file_with_newline    | awk 1 | awk 1 | awk 1 | wc -c
       6

# Character count of the file
$ cat file_without_newline | wc -c
       5

# Character count of the file changed by awk
$ cat file_without_newline | awk 1 | wc -c
       6

用函数计算行数

# Line count function used on stdin
$ cat file_with_newline    | wcl
       3

# Line count function used on stdin
$ cat file_without_newline | wcl
       3

# Line count function used on filenames passed as arguments
$ wcl file_without_newline  file_with_newline
       3
       3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-24
    • 2012-05-01
    • 1970-01-01
    • 2020-01-05
    • 2011-05-09
    相关资源
    最近更新 更多