I am writing a python scripts that reads the output of iperf3 client and fetches the required data in yml. Basically the script reads the output table and it has to capture the receiver's values for interval, transfer and bandwidth. To an extent the pattern matching is working, but the output is quite junky and not as expected. Please find my python script below:
import re
output = """
Connecting to host 9.10.21.01, port 5201
[ 4] local 9.17.201.011 port 44466 connected to 9.10.21.01 port 5201
[ ID] Interval Transfer Bandwidth Retr Cwnd
[ 4] 0.00-2.00 sec 1.71 GBytes 7.36 Gbits/sec 264 789 KBytes
[ 4] 2.00-4.00 sec 1.63 GBytes 6.99 Gbits/sec 133 865 KBytes
[ 4] 4.00-5.00 sec 732 MBytes 6.14 Gbits/sec 11 826 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-5.00 sec 4.06 GBytes 6.97 Gbits/sec 408 sender
[ 4] 0.00-5.00 sec 4.05 GBytes 6.96 Gbits/sec receiver
"""
receiver_line = re.search(r'\[\s+\d+\]\s+(.*?)\s+sec\s+(.*?)\s+(.*?)\s+receiver', output)
if receiver_line:
interval, transfer, bandwidth = receiver_line.groups()
output_yaml = f"Interval: {interval}\nTransfer: {transfer}\nBandwidth: {bandwidth}"
print(output_yaml)
else:
print("Receiver data not found in the output.")
My code seems to execute without any errors but somehow the pattern matching seems to be messed up. The output that is returned from the code is
Interval: 0.00-5.00
Transfer: 4.06 GBytes 6.97 Gbits/sec 408 sender
Bandwidth: [ 4] 0.00-5.00 sec 4.05 GBytes 6.96 Gbits/sec
The expected output should be something like shown below. Is there some tweaks I need to make or is there any other approach I can try?
Interval: 0.00-5.00
Transfer: 4.05 GBytes
Bandwidth: 6.96 Gbits/sec
Your code should work as expected if you use the following regex pattern:
import re
output = """
Connecting to host 9.10.21.01, port 5201
[ 4] local 9.17.201.011 port 44466 connected to 9.10.21.01 port 5201
[ ID] Interval Transfer Bandwidth Retr Cwnd
[ 4] 0.00-2.00 sec 1.71 GBytes 7.36 Gbits/sec 264 789 KBytes
[ 4] 2.00-4.00 sec 1.63 GBytes 6.99 Gbits/sec 133 865 KBytes
[ 4] 4.00-5.00 sec 732 MBytes 6.14 Gbits/sec 11 826 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-5.00 sec 4.06 GBytes 6.97 Gbits/sec 408 sender
[ 4] 0.00-5.00 sec 4.05 GBytes 6.96 Gbits/sec receiver
"""
receiver_line = re.search(r'([\d.]+-[\d.]+)\s+sec\s+([\d.]+\s+\w?Bytes)\s+([\d.]+\s+\w?bits/sec)\s+receiver', output)
if receiver_line:
interval, transfer, bandwidth = receiver_line.groups()
output_yaml = f"Interval: {interval}\nTransfer: {transfer}\nBandwidth: {bandwidth}"
print(output_yaml)
else:
print("Receiver data not found in the output.")
Alternatively since you indicated that column widths are fixed you could also iterate over lines and read out the different data fields with string indexing:
output = """
Connecting to host 9.10.21.01, port 5201
[ 4] local 9.17.201.011 port 44466 connected to 9.10.21.01 port 5201
[ ID] Interval Transfer Bandwidth Retr Cwnd
[ 4] 0.00-2.00 sec 1.71 GBytes 7.36 Gbits/sec 264 789 KBytes
[ 4] 2.00-4.00 sec 1.63 GBytes 6.99 Gbits/sec 133 865 KBytes
[ 4] 4.00-5.00 sec 732 MBytes 6.14 Gbits/sec 11 826 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-5.00 sec 4.06 GBytes 6.97 Gbits/sec 408 sender
[ 4] 0.00-5.00 sec 4.05 GBytes 6.96 Gbits/sec receiver
"""
for line in output.split('\n'):
interval = line[6:18].strip()
transfer = line[25:37]
bandwidth = line[38:53]
role = line[70:79].strip()
if role == 'receiver':
output_yaml = f"Interval: {interval}\nTransfer: {transfer}\nBandwidth: {bandwidth}"
print(output_yaml)
break
else:
print("Receiver data not found in the output.")