【问题标题】:Using sed to match on multiple patterns with one expression, and delete until a blank line使用 sed 匹配一个表达式的多个模式,并删除直到一个空行
【发布时间】:2016-07-12 20:48:09
【问题描述】:

在 RHEL 6.6 系统上,使用 ifconfig 和 GNU sed,我只想显示不是逻辑子接口的以太网接口或环回。

例如,输出不应包含接口名称为 eth0:134 或 lo 的接口记录。

到目前为止,我的方法是使用 sed 和两个表达式,第一个 /eth[0-9]:/ 匹配并包含所有包含 'ethN: 的行,包括之后的每一行,直到遇到空行,然后删除,以及要匹配的第二个表达式,/lo/ 和之后的所有行,直到一个空行,并删除它们。

例如:

[user@system ~]$ ifconfig -a | sed '/eth[0-9]:/,/^$/d; /lo/,/^$/d'


eth0     Link encap:Ethernet HWaddr 00:11:22:33:44:55
         inet addr:192.168.0.50 Bcast: 192.168.0.255 Mask:255.255.255.0
         UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
         RX packets:1024 ERRORS:0 DROPPED:0 OVERRUNS:0 FRAME:0
         TX packets:2048 ERRORS:0 DROPPED:0 OVERRUNS:0 FRAME:0
         collisions:0 txqueuelen:1000
         RX bytes:6455319 (6.1 MiB)  TX bytes: 258478  (252.4 KiB)

不想要的输出看起来像:

eth0:146 Link encap:Ethernet HWaddr 00:11:22:33:44:55
         inet addr:192.168.0.51 Bcast: 192.168.0.255 Mask:255.255.255.0
         UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

eth0:147 Link encap:Ethernet HWaddr 00:11:22:33:44:55
         inet addr:192.168.0.52 Bcast: 192.168.0.255 Mask:255.255.255.0
         UP BROADCAST RUNNING MULTICAST MTU:1500 Metric

eth0:148 Link encap:Ethernet HWaddr 00:11:22:33:44:55
         inet addr:192.168.0.53 Bcast: 192.168.0.255 Mask:255.255.255.0
         UP BROADCAST RUNNING MULTICAST MTU:1500 Metric

lo       Link encap:Local Lookback
         inet addr:127.0.0.1 Mask:255.0.0.0
         UP LOOPBACK RUNNING MTU:16436 Metric:1
         RX packets:605 errors:0 dropped:0 overruns:0 frame:0
         TX packets:605 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:0
         RX bytes:59008  (57.6 KiB)  TX bytes:59008  (57.6 KiB)

我喜欢这种删除从匹配行开始并包括匹配行直到遇到空行 (^$) 的所有输出行的方法,因为在包含接口名称的行之后有可变数量的额外行。在这种情况下,可以是 2 行、附加行或 6 个附加行。

此方法允许多输出 N 行,只要在显示的界面记录之间仍使用空行作为分隔符。

第二个表达式/lo/,/^$/d'如何与第一个结合起来?

也许另一种匹配(或不匹配)行的方法更好?

另一个问题是它只匹配前 10 个接口。不超过 10 个,但如果有的话,最好考虑一下。

我想在前 100 个接口上匹配如下内容:

^[1-9][0-9]?$|^100$

使用 awk 的解决方案也可以。

【问题讨论】:

  • 根据 Ed Morton 的评论,UN-desired 输出包含所有相同的行,只是第一列中的接口名称更改为包含 ethN: 和一个数值或字符串 lo,随后是特定于该特定接口的 6 行附加输出。
  • 已编辑以包含不需要的输出和附加说明。感谢您的反馈。
  • 我真的希望简单的“输入”和“想要的输出” - 这给了我们一些可以轻松测试的东西,而不是必须将来自“想要的输出”和“不需要的输出”的输入文件拼凑在一起并做出假设。话虽如此,你现在发布的内容确实有帮助,所以我更新了我的答案。

标签: regex bash awk sed


【解决方案1】:

听起来你只需要:

awk -v RS= -v ORS='\n\n' '$1~/^eth[0-9]+$/'

例如:

$ cat file
eth0:146 Link encap:Ethernet HWaddr 00:11:22:33:44:55
         inet addr:192.168.0.51 Bcast: 192.168.0.255 Mask:255.255.255.0
         UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

eth0     Link encap:Ethernet HWaddr 00:11:22:33:44:55
         inet addr:192.168.0.50 Bcast: 192.168.0.255 Mask:255.255.255.0
         UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
         RX packets:1024 ERRORS:0 DROPPED:0 OVERRUNS:0 FRAME:0
         TX packets:2048 ERRORS:0 DROPPED:0 OVERRUNS:0 FRAME:0
         collisions:0 txqueuelen:1000
         RX bytes:6455319 (6.1 MiB)  TX bytes: 258478  (252.4 KiB)

eth0:147 Link encap:Ethernet HWaddr 00:11:22:33:44:55
         inet addr:192.168.0.52 Bcast: 192.168.0.255 Mask:255.255.255.0
         UP BROADCAST RUNNING MULTICAST MTU:1500 Metric

eth0:148 Link encap:Ethernet HWaddr 00:11:22:33:44:55
         inet addr:192.168.0.53 Bcast: 192.168.0.255 Mask:255.255.255.0
         UP BROADCAST RUNNING MULTICAST MTU:1500 Metric

lo       Link encap:Local Lookback
         inet addr:127.0.0.1 Mask:255.0.0.0
         UP LOOPBACK RUNNING MTU:16436 Metric:1
         RX packets:605 errors:0 dropped:0 overruns:0 frame:0
         TX packets:605 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:0
         RX bytes:59008  (57.6 KiB)  TX bytes:59008  (57.6 KiB)

.

$ awk -v RS= -v ORS='\n\n' '$1~/^eth[0-9]+$/' file
eth0     Link encap:Ethernet HWaddr 00:11:22:33:44:55
         inet addr:192.168.0.50 Bcast: 192.168.0.255 Mask:255.255.255.0
         UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
         RX packets:1024 ERRORS:0 DROPPED:0 OVERRUNS:0 FRAME:0
         TX packets:2048 ERRORS:0 DROPPED:0 OVERRUNS:0 FRAME:0
         collisions:0 txqueuelen:1000
         RX bytes:6455319 (6.1 MiB)  TX bytes: 258478  (252.4 KiB)

如果您只想匹配 0 到 100 的接口编号,只需将其调整为:

awk -v RS= -v ORS='\n\n' '$1~/^eth([1-9]?[0-9]|100)$/'

【讨论】:

  • 帮我理解这里的“+$”是做什么的?在 [0-9] 之后立即停止匹配吗?我错过了如何匹配一位数字字段或两位数字字段的概念,但不是一位或两位数字字段后跟冒号“:”字符。谢谢
  • 尝试添加 {1,2} 与任何输出都不匹配。例如: ifconfig -a | awk -v RS= -v ORS='\n\n' '$1 ~ /^eth[0-9]{1,2}+$/' 什么都不返回 我认为这可行并且将匹配 0- 的数字范围99 awk -v RS= -v ORS='\n\n' '$1~/^eth[0-9]|[0-9][0-9]|100/ && $1 !~ /:/' 但是我重新使用两个表达式,正如@A.Danischewski 指出的那样,可能会有大量的 IO 损失。
  • + 表示1 or more repetitions of the preceding regexp element$ 表示end of string 所以[0-9]+$ 表示1 or more digits immediately followed by the end of string 所以它将匹配任何数字序列,但不会匹配任何其他数字字符,包括:
  • 你为什么要改变它——它按原样工作,对吧? {1,2} 表示 1 or 2 repetitions of the preceding regexp element+ 表示 1 or more repetitions of the preceding regexp element。我不知道您认为{1,2}+ 可能意味着什么,也不知道正则表达式引擎会如何处理它,所以我并不惊讶您使用它没有输出。使用复合条件 (/a/ && /b/) 与单个正则表达式 (/a.*b|b.*a/) 没有 IO 损失,因为 IO 没有区别,只是在被测试的条件下。 idk,但 A.Danichewski 可能在谈论 sed 命令链,而不是 awk。
  • 不需要改变,只是增加了我对+$的理解,从你上面的解释中获得了:)谢谢。
【解决方案2】:

试试:

ifconfig -a | sed -r '/(eth[0-9]{1,2}:|eth100:|lo)/,/^$/d'

{1,2} 表示上述一种或两种。所以,eth[0-9]{1,2} 匹配 eth 后跟一两个数字。

(A|B|C) 匹配 ABC。所以,(eth[0-9]{1,2}:|eth100:|lo) 匹配eth 与一个或两个数字 eth100 和一个冒号 lo

用于扩展正则表达式 (ERE) 的 -r。如果没有 -rsed 默认为基本正则表达式 (BRE)。在 GNU sed 上,BRE 的工作方式相同,但代价是额外的反斜杠:

ifconfig -a | sed '/\(eth[0-9]\{1,2\}:\|eth100:\|lo\)/,/^$/d'

BSD/OSX

BSD (OSX) sed 无法识别-r 选项。要获得扩展的正则表达式,请改用-E

ifconfig -a | sed -E '/(eth[0-9]{1,2}:|eth100:|lo)/,/^$/d'

-E 也适用于最新版本的 GNU sed

【讨论】:

  • 在程序的 1 或 2 中这是一个不错的技巧。谢谢你的例子。
  • @A.Danischewski 谢谢。在我的系统上,ifconfig doeslo 行有一个冒号。根据您的建议,我删除了冒号,以防万一。在另一个问题上,只有最新版本的 GNU sed 支持 -E 标志(并且它仍然未记录)。 OP 表示他正在使用 RHEL 6,我不清楚它是否足够新以支持 -E
  • 我的 rhel 6.6 机器上的 sed 版本是 GNU sed 版本 4.2.1 根据手册页,它不支持“-E”选项。但是,此框处于“气隙”环境中,可能没有可用的最新版本。
  • 我可以确认 '-E' 确实适用于具有 GNU sed 版本 4.2.1 的机器,但没有记录,也没有在手册页中作为参数列出。 “-E”不适用于带有 GNU sed 版本 4.1.5 的 RHEL 5.10 机器。使用 John1024 提供的命令时,它会打印 sed 的用法示例
  • @ChrisSmith 感谢您进行这项研究!这就是为什么在答案中我没有为您推荐-E。不过,只是为了确认一下,其他命令,那些使用-E的命令对你有用吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-07
  • 2019-06-18
  • 1970-01-01
  • 2018-04-30
  • 1970-01-01
  • 1970-01-01
  • 2020-08-04
相关资源
最近更新 更多