下面的代码(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'^servername\d* | \d{1,2}% |disk\d*')
result = [a for a in regex.findall(p)]
我需要帮助以某种方式在我的输出中包含str和int。谢谢你
答案 0 :(得分:0)
我个人将此解析为表而不是复杂的正则表达式,但如果你坚持,那么模式将是:
^(\S+).*?\n.*?\n(?:^.*?(\d+)%\s+(.*?)(?:\s|$))+
可以为每个服务器条目提供匹配,并在每个组下面提供:["servername300", "16", "/data/disk1", "36", "/data/disk10", etc.]
然而,Python的正则表达式(以及大多数正则表达式引擎)会覆盖重复的捕获组,只为您提供最后一次捕获,因此在您的示例数据上运行上述内容只会产生{{1 }}。当然,您可以构建模式以包含您可能期望的多个磁盘的可选捕获,或者为重复组播放范围属性,直到您全部耗尽它们,但这很快就会变得非常难看,所以......
您可以拆分作业 - 一种模式隔离服务器条目,另一种模式提取磁盘使用数据,然后找到记录服务器和磁盘数据的最小值和最大值,如:
[["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])]
,其中包含密钥的服务器名称和每个磁盘的dict
对列表。