提取文件中匹配正则表达式的所有行

Posted

技术标签:

【中文标题】提取文件中匹配正则表达式的所有行【英文标题】:Extract All Lines within a File that Matches Regular Expression 【发布时间】:2020-08-27 23:32:45 【问题描述】:

我有一个包含 dig 命令输出的 50k 行文件;我想提取与所有 IPv4 专用网络类 (RFC1918) 的正则表达式匹配的所有行。下面提供了一个示例,其中包含用于演示的模型值:

主输入文件:

; <<>> DiG 9.10.6 <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19663
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;google.com.            IN  A

;; ANSWER SECTION:
google.com.     135 IN  A   192.168.0.1

;; Query time: 38 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Tue May 12 17:40:16 AEST 2020
;; MSG SIZE  rcvd: 55

; <<>> DiG 9.10.6 <<>> transfer.me
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7906
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;transfer.me.           IN  A

;; ANSWER SECTION:
transfer.me.        7200    IN  A   10.216.41.127

;; Query time: 588 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Tue May 12 17:40:36 AEST 2020
;; MSG SIZE  rcvd: 56

期望的输出:

google.com.     135 IN  A   192.168.0.1
transfer.me.        7200    IN  A   10.216.41.127

我已经有了正则表达式,所以这只是一个如何将它们放在一起以获得所需输出的问题。

A 类网络:

(10)(\.([2]([0-5][0-5]|[01234][6-9])|[1][0-9][0-9]|[1-9][0-9]|[0-9]))3

B 类网络:

(172)\.(1[6-9]|2[0-9]|3[0-1])(\.(2[0-4][0-9]|25[0-5]|[1][0-9][0-9]|[1-9][0-9]|[0-9]))2

C类网络:

(192)\.(168)(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]))2

希望获得有关 UNIX CLI 实用程序、甚至更好的 Python 或 Perl 脚本的帮助。

【问题讨论】:

【参考方案1】:

这个问题没什么特别的。

您已经为每个网络类定义了正则表达式,让我们使用它

use strict;
use warnings;
use feature 'say';

my $re_classA = qr/(10)(\.([2]([0-5][0-5]|[01234][6-9])|[1][0-9][0-9]|[1-9][0-9]|[0-9]))3/;
my $re_classB = qr/(172)\.(1[6-9]|2[0-9]|3[0-1])(\.(2[0-4][0-9]|25[0-5]|[1][0-9][0-9]|[1-9][0-9]|[0-9]))2/;
my $re_classC = qr/(192)\.(168)(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]))2/;

while(<DATA>) 
    chomp;
    next if /^;/;
    say if /$re_classA/;
    say if /$re_classB/;
    say if /$re_classC/;


__DATA__

; <<>> DiG 9.10.6 <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19663
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;google.com.            IN  A

;; ANSWER SECTION:
google.com.     135 IN  A   192.168.0.1

;; Query time: 38 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Tue May 12 17:40:16 AEST 2020
;; MSG SIZE  rcvd: 55

; <<>> DiG 9.10.6 <<>> transfer.me
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7906
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;transfer.me.           IN  A

;; ANSWER SECTION:
transfer.me.        7200    IN  A   10.216.41.127

;; Query time: 588 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Tue May 12 17:40:36 AEST 2020
;; MSG SIZE  rcvd: 56

输出

google.com.     135 IN  A   192.168.0.1
transfer.me.        7200    IN  A   10.216.41.127

【讨论】:

谢谢伙计,这正是我所追求的。 @Jase -- next if /^;/; 可以替换为 next unless /^[^;].*?\d2,3\.\d1,3\.\d1,3.\d1,3\b/; - 进程行仅当它不以 ; 开头并且可能有任何后跟 IP 地址(2 或 3 位数字后跟 @ 987654326@,然后是 1 到 3 位数字,然后是 .,然后是 1 到 3 位数字,然后是 .,然后是 1 到 3 位数字)。

以上是关于提取文件中匹配正则表达式的所有行的主要内容,如果未能解决你的问题,请参考以下文章

用正则表达式regexp进行高级搜索数据

php 正则表达式 匹配网站内容

从文件中读取索引“n”低于与给定正则表达式匹配的行的所有行

如何匹配文件中的某些单词并列出该匹配单词的所有行? (没有正则表达式)

可选文件扩展名的正则表达式匹配

Java提取文本文档中的所有网址(小案例介绍正则基础知识)