One thing I've noticed in all systems I've access to: df with option -P prints in whitespace aligned columns. This means that the headers are the same width (padded with whitespace) as the rest of the items. Building on the7erm's answer, this uses the size of the header to ensure that it gets the whole mount point, even if there is a space in it.
This has been tested on Ubuntu 14.04, 16.04, and FreeBSD 9.2.
I've solved this two different ways, the first is a direct answer to the OP's question, giving 6 columns, each of which starts with the header, and then has each mountpoint in order below it:
import pprint
import subprocess
import re
DF_OPTIONS = "-PlaTh" # remove h if you want bytes.
# Get the entire output of df
dfdata = subprocess.getoutput("df " + DF_OPTIONS)
# Split it based on newlines
lines = dfdata.split("\n")
dfout = {}
headers = []
# Grab the headers, retain whitespace!
# df formats in such a way that each column header has trailing whitespace
# so the header is equal to the maximum column width. We want to retain
# this for len()
headersplit = re.split(r'(\s+)', lines[0].replace("Mounted on","Mounted_on "))
headers = [i+j for i,j in zip(headersplit[0::2],headersplit[1::2])]
for hi,head in enumerate(headers):
dfout[hi] = [head.strip()]
for line in lines[1:]:
pos = 0
dfstruct = {}
for hi,head in enumerate(headers):
# For the last item, grab the rest of the line
if head == headers[-1]:
item = line[pos:]
else:
# Get the current item
item = line[pos:pos+len(head)]
pos = pos + len(head)
#Strip whitespace and add it to the list
dfstruct[head.strip()] = item.strip()
dfout[hi].append(item.strip())
pprint.pprint(dfout)
The second is more useful to me, and the solution to why I stumbled upon this question in the first place. This puts the information into an array of dicts:
import pprint
import subprocess
import re
DF_OPTIONS = "-PlaTh" # remove h if you want bytes.
# Get the entire output of df
dfdata = subprocess.getoutput("df " + DF_OPTIONS)
# Split it based on newlines
lines = dfdata.split("\n")
dfout = []
headers = []
# Grab the headers, retain whitespace!
# df formats in such a way that each column header has trailing whitespace
# so the header is equal to the maximum column width. We want to retain
# this for len()
headersplit = re.split(r'(\s+)', lines[0].replace("Mounted on","Mounted_on "))
headers = [i+j for i,j in zip(headersplit[0::2],headersplit[1::2])]
for line in lines[1:]:
pos = 0
dfstruct = {}
for head in headers:
# For the last item, grab the rest of the line
if head == headers[-1]:
item = line[pos:]
else:
# Get the current item
item = line[pos:pos+len(head)]
pos = pos + len(head)
#Strip whitespace for our own structure
dfstruct[head.strip()] = item.strip()
dfout.append(dfstruct)
pprint.pprint(dfout)