麻烦只从文件

时间:2016-07-31 08:03:45

标签: linux bash unix grep

我无法从区域文件中找到我想要的唯一10位数字。

示例区域文件是:

> cat /var/named/test.com.db
; cPanel first:11.11.0-BETA_16994 (update_time):1468656855 Cpanel::ZoneFile::VERSION:1.3 hostname:server.test.com latest:11.56.0.13
; Zone file for test.com
$TTL 14400
test.com.      86400   IN      SOA     ns1.test.com.     cpanel.test.com.  (
                                                2016071602 ;Serial Number
                                                14400 ;refresh
                                                7200 ;retry
                                                2419200 ;expire
                                                43200   )
; test.com.    86400   IN      SOA     ns1.test.com.       serveralerts.test.com.        ( ; Previous value removed by cPanel restore auto-merge on 20160510102706 GMT
;                                               2015061700 ;Serial Number ; Previous value removed by cPanel restore auto-merge on 20160510102706 GMT
;                                               86400 ;refresh ; Previous value removed by cPanel restore auto-merge on 20160510102706 GMT
;                                               7200 ;retry ; Previous value removed by cPanel restore auto-merge on 20160510102706 GMT
;                                               3600000 ;expire ; Previous value removed by cPanel restore auto-merge on 20160510102706 GMT
;                                               86400 ;minimum ; Previous value removed by cPanel restore auto-merge on 20160510102706 GMT
;       ) ; Previous value removed by cPanel restore auto-merge on 20160510102706 GMT

test.com.      86400   IN      NS      ns1.test.com.
test.com.      86400   IN      NS      ns2.test.com.
; test.com.    86400   IN      NS      ns1.test.com. ; Previous value removed by cPanel restore auto-merge on 20160510102706 GMT
; test.com.    86400   IN      NS      ns2.test.com. ; Previous value removed by cPanel restore auto-merge on 20160510102706 GMT


test.com.      14400   IN      A       192.168.1.100

localhost       14400   IN      A       127.0.0.1

test.com.      14400   IN      MX      0       test.com.

mail    14400   IN      CNAME   test.com.
www     14400   IN      CNAME   test.com.
ftp     14400   IN      CNAME   test.com.
webdisk 14400   IN      A       192.168.1.100
cpcalendars     14400   IN      A       192.168.1.100
test.com. IN TXT "v=spf1 +a +mx +ip4:192.168.1.100 ~all"

我想从grep输出的区域文件中只看到当前序列号 2016071602

为此,我尝试了命令:

grep -o '2016[0-9]\{6\}' /var/named/test.com.db

但它会输出所有这些垃圾。我的意思是偶数超过10的数字

我得到的结果是:

> grep -o '2016[0-9]\{6\}' /var/named/test.com.db                     
2016071602
2016051010
2016051010
2016051010
2016051010
2016051010
2016051010
2016051010
2016051010
2016051010

你能帮我把它过滤掉吗?一旦我能够纠正这个,我将很乐意继续在服务器上更新质量区域。

3 个答案:

答案 0 :(得分:3)

问题是2016[0-9]\{6\}匹配以2016开头的任何十位数字。它对这些数字之前或之后的内容没有任何限制。

尝试:

$ grep -Eo '2016[0-9]{6}[^0-9]' test.com.db 
2016071602 

或者,更好的是,如果你的grep支持-P,就像在Linux系统上一样:

$ grep -Po '2016[0-9]{6}(?=[^0-9])' test.com.db 
2016071602

此处,(?=[^0-9])是预示:它要求非数字跟随数字,但不会包含在匹配中。

或者,要获得“序列号”后面的数字:

$ grep -Po '2016[0-9]{6}(?=.*Serial Number)' test.com.db 
2016071602

这要求十位数字后面的字符必须是非数字。 ([^0-9]匹配任何非数字,因为^是对其后的内容的否定。)

为了确保这适用于unicode字体,您可能希望将[0-9]替换为其unicode安全替代方案:[[:digit:]]

$ grep -Po '2016[[:digit:]]{6}(?=[^[:digit:]])' test.com.db 
2016071602

答案 1 :(得分:1)

如果你需要一个上下文,那么

server = new WebSocketServer(); var serverConfig = new SuperSocket.SocketBase.Config.ServerConfig(); serverConfig.MaxConnectionNumber = 100000; //serverConfig.Port = 222; //serverConfig.ListenBacklog = 5000; var list = new List<SuperSocket.SocketBase.Config.ListenerConfig>(20); int port = 223; for (int i = 0; i < 1;i++) { var listener = new SuperSocket.SocketBase.Config.ListenerConfig(); listener.Port = port; listener.Backlog = 1000; listener.Ip = "Any"; listener.Security = "None"; port++; list.Add(listener); } serverConfig.Listeners = list; server.Setup(serverConfig); server.NewSessionConnected += server_NewSessionConnected; server.SessionClosed += server_SessionClosed; server.NewMessageReceived += server_NewMessageReceived; server.Start(); 不是最好的工具,也就是说,模式周围的一些文本没有在输出中包含该文本。 带有捕获组的grep可以更好地工作,例如:

sed

这将打印出sed -ne 's/.*\(2016[0-9]\{6\}\).*Serial Number.*/\1/p' filename 中捕获的模式, 在同一行后面跟着“序列号”。 如果这还不够好,你可以相应地调整模式, 使其更加严格,以消除进一步的误报。

另一个有用的技巧是将有趣的模式包含在\(...\)中以使其与单词边界匹配:

\<...\>

这样,2016年之前的数字或超过10位数字的情况将不匹配。

答案 2 :(得分:1)

使用GNU grep:

grep '^[^;].*Serial Number' file | grep -o '2016[0-9]\{6\}'

输出:

2016071602