【问题标题】:Why does Linux grep not give the correct count for line breaks?为什么 Linux grep 没有给出正确的换行计数?
【发布时间】:2014-01-05 01:07:27
【问题描述】:

在 Ubuntu 10.04.4 LTS 上,我做了如下的小测试,得到了令人惊讶的结果:

首先,我创建了一个包含 5 行的文件并将其命名为 a.txt:

echo -e "1\n2\n3\n4\n5" > a.txt
$ cat a.txt
1
2
3
4
5

然后我运行wc 来统计行数

$ wc -l a.txt
5 a.txt

但是,当我运行 grep 来计算有换行符的行数时,我得到了一个我不明白的答案:

$ grep -c -P '\n' a.txt
3

我的问题是:grep 是如何得到这个号码的?不应该是4吗?

【问题讨论】:

  • 在另一个 Ubuntu 系统上,我做了同样的测试,grep 返回 0。
  • 它应该返回 0,grep 只会搜索 within 一行。它不应该看到换行符。这 3 的来源令人费解。
  • 不,假设是错误的;如果 grep 确实计算换行符,它将是 5 而不是 4。echo 将再添加一个换行符。如果您不希望 echo 发出换行符,则需要 -n 选项。
  • 既然有wc -l,为什么还要使用grep

标签: linux bash shell unix grep


【解决方案1】:

请阅读精美手册!

 seq 1 5  | wc -l
 5

 seq 1 5  | grep -ac $'\n'
 5

我不明白问题出在哪里!?

 seq 1 5  | hd
 00000000  31 0a 32 0a 33 0a 34 0a  35 0a                    |1.2.3.4.5.|

说明:

  • -a 开关告诉grep二进制 模式打开文件。 IE 不关心文本格式

  • $'\n' 语法由bash 自己解析,在运行grep 之前。这样做可以将 控制字符 作为参数传递给 下的任何命令。

【讨论】:

  • 酷。这行得通。请解释一下为什么使用“-a”选项,以及为什么在“\n”之前加上“$”?
【解决方案2】:

Grep 看不到换行符。它搜索内联模式。 考虑使用grep -c -P '$' a.txt 来匹配每一行的结尾。

【讨论】:

  • 你错了:grep -a 处理 binary 文件...见my anser
【解决方案3】:

换行符不是行的一部分。 grep 使用换行符作为记录分隔符,并将其从行中删除,以便 $ 的模式按预期工作。例如,要搜索以foo 结尾的行,您可以使用模式foo$ 而不是foo\n$。那会很不方便。

所以grep -c -P '\n' a.txt 应该给你 0。如果你得到 3,那听起来很奇怪,但也许可以解释 man grep 中的高度实验性评论:

   -P, --perl-regexp
          Interpret  PATTERN  as  a  Perl  regular  expression  (PCRE, see
          below).  This is highly experimental and grep  -P  may  warn  of
          unimplemented features.

我使用的是 Debian/Wheezy,它比 Ubuntu 10.04 更新得多。如果-P 今天是“高度实验性的”,那么不难想象它在旧系统中是错误的。不过这只是猜测。

要计算换行符的数量,请使用wc -l,而不是grep -c hack。

顺便说一句,有趣的是:

$ printf hello >> a.txt 
$ wc -l a.txt 
5 a.txt
$ grep -c '' a.txt 
6

也就是说,printf 不打印换行符,所以在我们将“hello”附加到a.txt 之后,文件末尾不会有换行符。所以wc -l 计算换行符,不完全是“行”,grep ''(空字符串)匹配所有行。

【讨论】:

    【解决方案4】:

    我想你想用

    $ grep -c -P "." a.txt
    5
    $ echo "6" >> a.txt
    $ grep -c -P "." a.txt
    6
    $ cat a.txt
    1
    2
    3
    4
    5
    6
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-12
      相关资源
      最近更新 更多