带有正则表达式输出的磁盘使用情况输出



下面的代码(p =)产生此输出

servername300 | SUCCESS | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       3.7T  1.3T  2.4T  16% /data/disk1
/dev/sdj1       3.7T  1.3T  2.4T  36% /data/disk10
/dev/sdk1       3.7T  1.3T  2.4T  36% /data/disk11
servername290 | SUCCESS | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       3.7T  1.4T  2.4T  36% /data/disk1
/dev/sdj1       3.7T  1.4T  2.4T  37% /data/disk10
/dev/sdk1       3.7T  1.4T  2.4T  37% /data/disk11

此代码获取此输出并计算磁盘是否不平衡超过 5%。

import re
from subprocess import Popen, PIPE
p = subprocess.check_output(["ansible","dev-data","-m","shell","-a","df -h /data/disk*"], stdin=PIPE)
regex = re.compile(r'd{1,2}%')
result = [int(a[:-1]) for a in regex.findall(p)]
print min (result)
print max (result)
if max(result) - min(result) > 5:
print("Imbalanced!")
else:
print("Balanced!")

这将给我输出

"""16 37 Imbalanced"""

我想要的是在我的输出中包含服务器和磁盘,例如servername300 16 Disk 1, servername290 37 Disk 10.

这是我到目前为止尝试过的

regex1 = re.compile(r'^servernamed* | d{1,2}% |diskd*')
result = [a for a in regex.findall(p)]

我需要帮助以某种方式在我的输出中包含 str 和 int。谢谢

我个人会将其解析为表而不是执行复杂的正则表达式,但如果您坚持,模式将是:

^(S+).*?n.*?n(?:^.*?(d+)%s+(.*?)(?:s|$))+

这将为您提供每个服务器条目的匹配项,并在每个组下,例如:["servername300", "16", "/data/disk1", "36", "/data/disk10", etc.]

但是,Python 的正则表达式(以及与此相关的大多数正则表达式引擎)覆盖重复的捕获组以仅为您提供最后一次捕获,因此对示例数据运行上述操作只会产生[["servername300", "36", "/data/disk11"], ["servername290", "37", "/data/disk11"]]。当然,您可以构建模式以包含您可能期望的任意数量的磁盘的可选捕获,或者使用重复组的范围属性,直到将它们全部用尽,但这很快就会变得非常丑陋,所以......

您可以拆分作业 - 一种模式用于隔离服务器条目,另一种模式用于提取磁盘使用情况数据,然后只需找到记录服务器和磁盘数据的最小值和最大值,例如:

import re
import subprocess
p = subprocess.check_output(["ansible","dev-data","-m","shell","-a","df -h /data/disk*"],
stdin=subprocess.PIPE)
# our patterns, self explanatory
SERVER_MATCH = re.compile(r"(?!</)(S+)(?:.*?n){2}((?:^/.*(?:n|$))+)", re.MULTILINE)
DISK_MATCH = re.compile(r"(d+)%s+(S+)")
min_use = 100, None, None  # store for minimum usage entry
max_use = 0, None, None    # store for maximum usage entry
for server in SERVER_MATCH.findall(p):  # get all the servers + their disks
for disk in DISK_MATCH.findall(server[1]):  # get each disk (usage + mount point)
disk_usage = int(disk[0])  # convert the usage to integer
if disk_usage < min_use[0]:  # if current disk's usage is smaller than min_usage
min_use = (disk_usage, server[0], disk[1])  # replace entry
if disk_usage > max_use[0]:  # if current disk's usage is smaller than max_usage
max_use = (disk_usage, server[0], disk[1])  # replace entry
if max_use[0] - min_use[0] > 5:  # check min/max entries for larger discrepancy than 5...
print("Imbalanced!")  # Imbalanced, print the info:
print("tMIN: {1} {0}% {2}".format(*min_use)) 
print("tMAX: {1} {0}% {2}".format(*max_use))
else:
print("Balanced!")

这应该给你一个很好的:

Imbalanced!
servername300 16% /data/disk1
servername290 37% /data/disk10

示例数据的输出。这足以找到不平衡的范围,但如果您想保留所有记录以进行比最小值/最大值更可靠的分析,您可以使用:

servers = {}
for server in SERVER_MATCH.findall(data):
servers[server[0]] = [(int(disk[0]), disk[1]) for disk in DISK_MATCH.findall(server[1])]

这将为您提供一个包含密钥的服务器名称及其每个磁盘的(usage, disk_name)对列表的dict

最新更新