如何在 ubuntu 中使用 grep 计算新行数

How to count new lines using grep in ubuntu

(最后一点,在问题的开头:我在提问之前已经解决了这个问题,滚动到最后)

我正在尝试解析一个大文件,在进行更改之前,我想我会 运行 一些 "simple" 测试来确认我得到了所需的输出,但是我来不及了。

这里是文件格式的捕获:

00000030  32 2e 31 2e 30 65 2c 0d  0a 43 4c 49 45 4e 54 5f  |2.1.0e,..CLIENT_|
00000040  44 45 4d 4f 2c 31 2c 31  2c 22 4c 4b 44 55 41 32  |DEMO,1,1,"LKDUA2|

我想做的是将所有换行符 \x0d\x0a\r\n 转换成我为此目的使用的 \x09\t 的其他内容,这样我可以重新解析它并且只将其中的一些转换回新行。

我意识到可能有更好的方法来做到这一点,但我正在尝试使用我已经(认为我)知道的东西。

首先我运行一些试验:

tr -s '\r\n' '\t' < orig > o.rnt
tr -s '\n' '\t' < orig > o.nt
tr -s '\r' '\t' < orig > o.rt

和文件大小:

$ ls -l o*
-rw-r----- 1 madivad madivad 620519 Oct 30 09:41 orig
-rw-rw-r-- 1 madivad madivad 620519 Oct 30 09:26 o.nt
-rw-rw-r-- 1 madivad madivad 620519 Oct 30 09:26 o.rt
-rw-rw-r-- 1 madivad madivad 615271 Oct 30 09:40 o.rnt

这些结果符合预期。区别是 5248,这是换行符的数量。到目前为止,还不错。

额外的选项卡发生了什么事

我又添加了一项测试,结果与预期不符:

tr -s '\r\n' '\t\t' < orig > o.rntt

-rw-rw-r-- 1 madivad madivad 615271 Oct 30 09:40 o.rntt

我原以为是 620519,但十六进制转储确认仅添加了 1x \t

00000030  32 2e 31 2e 30 65 2c 09  43 4c 49 45 4e 54 5f 44  |2.1.0e,.CLIENT_D|

(注意:这个(Q1)更多的是一个附带的问题,我是在确认了一切才问这个问题的时候才发现的,下面是我真正的问题)

如何正确测试或计数 'newline'

在我的 运行 测试中,我想计算 newline 的出现次数,我用几种方法确认了这一点,结果得到了正确的 5248... 一些结果。 \n 似乎没有被正确解析。

$ grep -c ^ orig
5248
$ grep -c -P '\r' orig
5248
$ grep -c -P '\r' o.rt
5248
$ grep -c -P '\x0d' o.rt
5248
$ grep -c -P '\t' o.rnt
1
$ grep -c -P '\n' orig
0
$ grep -c -P '\x0a' orig
0
$ grep -c -P '\r\n' orig
0

转换和测试确认

$ hexdump -C -s 48 -n 32 orig
00000030  32 2e 31 2e 30 65 2c 0d  0a 43 4c 49 45 4e 54 5f  |2.1.0e,..CLIENT_|

$ hexdump -C -s 48 -n 32 o.rt
00000030  32 2e 31 2e 30 65 2c 09  0a 43 4c 49 45 4e 54 5f  |2.1.0e,..CLIENT_|

$ hexdump -C -s 48 -n 32 o.nt
00000030  32 2e 31 2e 30 65 2c 0d  09 43 4c 49 45 4e 54 5f  |2.1.0e,..CLIENT_|

$ hexdump -C -s 48 -n 32 o.rnt
00000030  32 2e 31 2e 30 65 2c 09  43 4c 49 45 4e 54 5f 44  |2.1.0e,.CLIENT_D|

对于输出文件,tr '\r\n' '\t' < orig > o.rnt 似乎做对了,但我的 grep 测试是错误的:

$ hexdump -C -n 600 o.rnt | grep -P ' 09 '
00000030  32 2e 31 2e 30 65 2c 09  43 4c 49 45 4e 54 5f 44  |2.1.0e,.CLIENT_D|
00000110  2c 22 22 2c 31 2c 2c 09  43 4c 49 45 4e 54 5f 41  |,"",1,,.CLIENT_A|
000001a0  22 22 2c 30 2c 22 22 2c  09 43 4c 49 45 4e 54 5f  |"",0,"",.CLIENT_|
00000200  73 65 2c 46 61 6c 73 65  2c 30 2c 09 43 4c 49 45  |se,False,0,.CLIE|
00000230  31 2c 09 43 4c 49 45 4e  54 5f 43 4e 53 4e 54 2c  |1,.CLIENT_CNSNT,|

$ grep -c -P '\t' o.rnt
1

我用过的地方:tr -s '\n' '\t' < orig > o.nt它似乎也有效,我的测试又是错误的:

$ hexdump -C -n 600 o.nt | grep -P ' 09 '
00000030  32 2e 31 2e 30 65 2c 0d  09 43 4c 49 45 4e 54 5f  |2.1.0e,..CLIENT_|
00000110  30 2c 22 22 2c 31 2c 2c  0d 09 43 4c 49 45 4e 54  |0,"",1,,..CLIENT|
000001a0  22 2c 22 22 2c 30 2c 22  22 2c 0d 09 43 4c 49 45  |","",0,"",..CLIE|
00000200  46 61 6c 73 65 2c 46 61  6c 73 65 2c 30 2c 0d 09  |False,False,0,..|
00000230  2c 31 32 30 31 2c 0d 09  43 4c 49 45 4e 54 5f 43  |,1201,..CLIENT_C|

$ grep -c -P '\t' o.nt
1

谢谢

我不想继续前进,直到我明白我哪里出了问题,这样我才不会进一步加剧问题:)

我解决了

如上所说,其实我已经算出来了,但是现在可以问一下:

1。有没有更好的方法?

这是我想出的测试,如果有任何改进,我会很高兴:

$ grep -o -P '\t' o.nt | wc -l
5249

哦,是的,还有一个额外的 \t 因为文件中实际上有一个额外的选项卡(长话短说)

回想起来,我将如何使用 hexdump 计算它并注意线交叉?即计数或显示 0D 0A

在进行最终测试时,我终于搞定了

我已经准备好 post 这个问题了,就像我过去多次遇到的那样,问一个 stackexchange 问题让我在 post 之前就知道了答案编辑。

我已经处理这个问题一个多小时了,但看到我的方法有误。我仍在 post 进行此操作,因为我花了这么长时间来学习,也许它可以防止其他人这样做:/

我忘记了 grep -c 会计算行数,通过删除 newline 字符,文件中将只有一行 :(

我想出了这个测试:

$ grep -o -P '\t' o.nt | wc -l
5249