在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?
答案 0 :(得分:3)
Grep无法看到换行符。它搜索内联模式。
请考虑使用grep -c -P '$' a.txt
来匹配每行的结尾。
答案 1 :(得分:3)
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
之前解析。这样做可以将控制字符作为参数传递给bash下的任何命令。
答案 2 :(得分:2)
换行符不是行的一部分。 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
黑客。
$ printf hello >> a.txt
$ wc -l a.txt
5 a.txt
$ grep -c '' a.txt
6
也就是说,printf
不会打印换行符,因此在我们向a.txt
追加“hello”后,文件末尾不会有换行符。因此wc -l
计算换行符,而不是“行”,grep ''
(空字符串)匹配所有行。
答案 3 :(得分:0)
我想你想用
$ 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