From a023001cd350e320ce30f47af214ed7a9bb43185 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 22 Oct 2019 11:10:11 -0700 Subject: [PATCH] add df, env, and free parsers --- README.md | 73 ++++++++++++++++++++++++++++++++++++++++++++++ changelog.txt | 5 ++++ jc/jc.py | 17 ++++++++++- jc/parsers/df.py | 56 +++++++++++++++++++++++++++++++++++ jc/parsers/env.py | 53 +++++++++++++++++++++++++++++++++ jc/parsers/free.py | 23 +++++++++++++++ 6 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 jc/parsers/df.py create mode 100644 jc/parsers/env.py create mode 100644 jc/parsers/free.py diff --git a/README.md b/README.md index bb7a2806..cfcb99d6 100755 --- a/README.md +++ b/README.md @@ -70,6 +70,79 @@ Options: - `-p` specifies whether to pretty format the JSON output ## Examples +### df +``` +$ df | jc --df -p +[ + { + "Filesystem": "/dev/disk1s1", + "512-blocks": "976490576", + "Used": "268326664", + "Available": "702568152", + "Capacity": "28%", + "iused": "1395740", + "ifree": "9223372036853380067", + "%iused": "0%", + "Mounted": "/" + }, + { + "Filesystem": "devfs", + "512-blocks": "680", + "Used": "680", + "Available": "0", + "Capacity": "100%", + "iused": "1178", + "ifree": "0", + "%iused": "100%", + "Mounted": "/dev" + }, + { + "Filesystem": "map", + "512-blocks": "auto_home", + "Used": "0", + "Available": "0", + "Capacity": "0", + "iused": "100%", + "ifree": "0", + "%iused": "0", + "Mounted": "100%", + "on": "/home" + } +] +``` +### env +``` +$ env | jc --env -p +[ + { + "TERM": "xterm-256color" + }, + { + "SHELL": "/bin/bash" + }, + { + "USER": "root" + }, + { + "PATH": "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" + }, + { + "PWD": "/bin" + }, + { + "LANG": "en_US.UTF-8" + }, + { + "HOME": "/root" + }, + { + "_": "/usr/bin/env" + } +] +``` +### df +``` +``` ### ifconfig ``` $ ifconfig | jc --ifconfig -p diff --git a/changelog.txt b/changelog.txt index 98ff7973..2c2b9246 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,10 @@ jc changelog +2019xxxx v0.x.x +- Add env parser +- Add df parser +- Add free parser + 20191021 v0.6.4 - Flatten netstat parser output - Clean up argument parsing diff --git a/jc/jc.py b/jc/jc.py index 9adba38c..de436b0b 100755 --- a/jc/jc.py +++ b/jc/jc.py @@ -6,6 +6,9 @@ Main input module import sys import json +import jc.parsers.df +import jc.parsers.env +import jc.parsers.free import jc.parsers.ifconfig import jc.parsers.ls import jc.parsers.netstat @@ -20,7 +23,16 @@ def main(): if '-p' in sys.argv: pretty = True - if '--ifconfig' in sys.argv: + if '--df' in sys.argv: + result = jc.parsers.df.parse(data) + + elif '--env' in sys.argv: + result = jc.parsers.env.parse(data) + + elif '--free' in sys.argv: + result = jc.parsers.free.parse(data) + + elif '--ifconfig' in sys.argv: result = jc.parsers.ifconfig.parse(data) elif '--ls' in sys.argv: @@ -39,6 +51,9 @@ def main(): print('jc: missing arguments', file=sys.stderr) print('Usage: jc [parser] [options]\n', file=sys.stderr) print('Parsers:', file=sys.stderr) + print(' --df df parser', file=sys.stderr) + print(' --env env parser', file=sys.stderr) + print(' --free free parser', file=sys.stderr) print(' --ifconfig iconfig parser', file=sys.stderr) print(' --ls ls parser', file=sys.stderr) print(' --netstat netstat parser', file=sys.stderr) diff --git a/jc/parsers/df.py b/jc/parsers/df.py new file mode 100644 index 00000000..990e982d --- /dev/null +++ b/jc/parsers/df.py @@ -0,0 +1,56 @@ +"""jc - JSON CLI output utility df Parser + +Usage: + specify --df as the first argument if the piped input is coming from df + +Example: + +$ df | jc --df -p +[ + { + "Filesystem": "/dev/disk1s1", + "512-blocks": "976490576", + "Used": "268326664", + "Available": "702568152", + "Capacity": "28%", + "iused": "1395740", + "ifree": "9223372036853380067", + "%iused": "0%", + "Mounted": "/" + }, + { + "Filesystem": "devfs", + "512-blocks": "680", + "Used": "680", + "Available": "0", + "Capacity": "100%", + "iused": "1178", + "ifree": "0", + "%iused": "100%", + "Mounted": "/dev" + }, + { + "Filesystem": "map", + "512-blocks": "auto_home", + "Used": "0", + "Available": "0", + "Capacity": "0", + "iused": "100%", + "ifree": "0", + "%iused": "0", + "Mounted": "100%", + "on": "/home" + } +] +""" + + +def parse(data): + + # code adapted from Conor Heine at: + # https://gist.github.com/cahna/43a1a3ff4d075bcd71f9d7120037a501 + + cleandata = data.splitlines() + headers = [h for h in ' '.join(cleandata[0].strip().split()).split() if h] + raw_data = map(lambda s: s.strip().split(None, len(headers) - 1), cleandata[1:]) + return [dict(zip(headers, r)) for r in raw_data] diff --git a/jc/parsers/env.py b/jc/parsers/env.py new file mode 100644 index 00000000..2cebc027 --- /dev/null +++ b/jc/parsers/env.py @@ -0,0 +1,53 @@ +"""jc - JSON CLI output utility env Parser + +Usage: + specify --env as the first argument if the piped input is coming from env + +Example: +$ env | jc --env -p +[ + { + "TERM": "xterm-256color" + }, + { + "SHELL": "/bin/bash" + }, + { + "USER": "root" + }, + { + "PATH": "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" + }, + { + "PWD": "/bin" + }, + { + "LANG": "en_US.UTF-8" + }, + { + "HOME": "/root" + }, + { + "_": "/usr/bin/env" + } +] +""" + + +def parse(data): + output = [] + + linedata = data.splitlines() + + # Clear any blank lines + cleandata = list(filter(None, linedata)) + + if cleandata: + + for entry in cleandata: + output_line = {} + parsed_line = entry.split('=', maxsplit=1) + output_line[parsed_line[0]] = parsed_line[1] + output.append(output_line) + + return output diff --git a/jc/parsers/free.py b/jc/parsers/free.py new file mode 100644 index 00000000..72a42d3a --- /dev/null +++ b/jc/parsers/free.py @@ -0,0 +1,23 @@ +"""jc - JSON CLI output utility free Parser + +Usage: + specify --free as the first argument if the piped input is coming from free + +Example: + + +""" + + +def parse(data): + + # code adapted from Conor Heine at: + # https://gist.github.com/cahna/43a1a3ff4d075bcd71f9d7120037a501 + + cleandata = data.splitlines() + headers = [h for h in ' '.join(cleandata[0].strip().split()).split() if h] + + headers.insert(0, "type") + + raw_data = map(lambda s: s.strip().split(None, len(headers) - 1), cleandata[1:]) + return [dict(zip(headers, r)) for r in raw_data]