I have a CSV file, one column of which is called Operating System and contains a string with values that look like this:
win-abc123
def456-windows
123123-WIN-ghi789
rhel-jkl012
45u8234dgf-redhat-mno345
pqr678-RHEL
In other words, the column value contains a substring somewhere inside of the string (front, middle, or end) indicating the operating system. The values could be one of win,windows,WIN,rhel,redhat,RHEL.
I want to examine the column value, and clean it up by replacing the entire column with either WIN or RHEL.
I have a clunky solution. Iterate over each row in the CSV, and iterate over each key, value pair in a operating system map. If it matches, replace the CSV value.
os_map = {'win':'WIN', 'windows': 'WIN', 'WIN':'WIN', 'rhel': 'RHEL', 'redhat': 'RHEL', 'RHEL': 'RHEL'}
for row in rows:
os = row[OPERATING_SYSTEM]
for key, value in os_map.iteritems():
if key in os:
row[OPERATING_SYSTEM] = value
break
Or, in java:
Map<String, String> osMap = new HashMap<String, String>();
osMap.put("win", "WIN");
osMap.put("windows", "WIN");
osMap.put("WIN", "WIN");
// Repeat for RHEL values
String os;
for (String[] row : rows) {
os = row[OPERATING_SYSTEM];
for (Map.Entry<String, String> entry: osMap.entrySet()) {
if (os.contains(entry.getKey())) {
row[OPERATING_SYSTEM] = entry.getValue();
break;
}
}
}
I don't like this because I'm iterating through the entire map (in the worst case) before I find a match. What is a more efficient way to solve this?
If the CSV columns were simply either win or windows, without the alphanumeric characters, I could instead do this:
os_map = {'win,windows,WIN': 'WIN', 'rhel,redhat,RHEL': 'RHEL'}
for key, value in os_map:
if key.contains(row[OPERATING_SYSTEM]):
row[OPERATING_SYSTEM] = value
break
But this is not the case.
In Python, you can do something along these lines:
test='''\
win-abc123
def456-windows
123123-WIN-ghi789
rhel-jkl012
45u8234dgf-redhat-mno345
pqr678-RHEL'''
from itertools import chain
os_map = {frozenset(['win', 'windows', 'WIN']):'WIN', frozenset(['rhel', 'redhat', 'RHEL',]): 'RHEL'}
all_os=set(chain(*os_map.keys()))
for line in test.splitlines():
tgt=filter(lambda e: e in all_os, line.split('-'))
if tgt:
print os_map[filter(lambda k: tgt[0] in k, os_map.keys())[0]]
You could also do a dict of regex:
import re
os_reg={re.compile(r'\b(win|windows|WIN)\b'):'WIN', re.compile(r'\b(rhel|redhat|RHEL)\b'): 'RHEL'}
for line in test.splitlines():
for pat, v in os_reg.items():
if pat.search(line):
print line, v
break
Or combine set and regex to do something like this:
os_map = {frozenset(['win', 'windows', 'WIN']):'WIN', frozenset(['rhel', 'redhat', 'RHEL',]): 'RHEL'}
for k, v in os_map.items():
test=re.sub(r'\b({})\b'.format('|'.join(k)), v, test)
for line in test.splitlines():
m=re.search(r'\b({})\b'.format('|'.join(os_map.values())), line)
if m:
print line, m.group(0)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With