mirror of
https://github.com/kellyjonbrazil/jc.git
synced 2026-04-03 17:44:07 +02:00
Compare commits
198 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ddabfaa05c | ||
|
|
f857523ca7 | ||
|
|
00d53858e8 | ||
|
|
c008167e66 | ||
|
|
102344a041 | ||
|
|
c865298ef3 | ||
|
|
6ac03faf93 | ||
|
|
49c2701743 | ||
|
|
d1a271b08e | ||
|
|
7388ad19b9 | ||
|
|
2e63cb5fad | ||
|
|
e7f14d02b1 | ||
|
|
873771d05a | ||
|
|
d7de122e36 | ||
|
|
4ef0434f53 | ||
|
|
1aa2c99259 | ||
|
|
c2450b27b0 | ||
|
|
14d6d8b84f | ||
|
|
f0e3846c03 | ||
|
|
6ba64f1128 | ||
|
|
13bcdbc6c9 | ||
|
|
cfba62db20 | ||
|
|
18fb69e36e | ||
|
|
474eb0f3fd | ||
|
|
7f47b53370 | ||
|
|
dc2907d3ce | ||
|
|
1af85811e0 | ||
|
|
1c1b19a478 | ||
|
|
66942d64ba | ||
|
|
2fb6ae08d7 | ||
|
|
bf8811e03e | ||
|
|
c8b502c571 | ||
|
|
81c11a975c | ||
|
|
0d370eb403 | ||
|
|
7492c3f1e3 | ||
|
|
515a8a84b7 | ||
|
|
dd6680efb2 | ||
|
|
a7158373cd | ||
|
|
6d50ec7199 | ||
|
|
95dbf98e8e | ||
|
|
d49323e4eb | ||
|
|
08c1e2aec9 | ||
|
|
a2c137df2e | ||
|
|
fe27dcdb8f | ||
|
|
028e136161 | ||
|
|
9a85a0a4d5 | ||
|
|
3a1cbc4d50 | ||
|
|
77d334f7f3 | ||
|
|
53cdf863ac | ||
|
|
7b7e7fe0fe | ||
|
|
0c03132847 | ||
|
|
3b81f7e2a1 | ||
|
|
3d76437b43 | ||
|
|
4bc54c78ce | ||
|
|
3d303a96b9 | ||
|
|
33c99d031d | ||
|
|
caf7e9f69a | ||
|
|
9449f1f5d5 | ||
|
|
6bad164b5e | ||
|
|
bb5ba7ddb1 | ||
|
|
8b2e01d540 | ||
|
|
ff1159b1de | ||
|
|
a2fd3202a0 | ||
|
|
7b53715b91 | ||
|
|
e05fc0a510 | ||
|
|
43604c33f6 | ||
|
|
eb67c484ff | ||
|
|
a7b7bdd467 | ||
|
|
ab06989a18 | ||
|
|
657b722f94 | ||
|
|
dd2aecad27 | ||
|
|
c82c5c5c64 | ||
|
|
a1761cd68f | ||
|
|
d618a7f583 | ||
|
|
831a42f660 | ||
|
|
3b36022e5a | ||
|
|
d01dfa25f1 | ||
|
|
395a99037b | ||
|
|
025986c51d | ||
|
|
c56b83093f | ||
|
|
7c712a4133 | ||
|
|
9a0cfe6dfa | ||
|
|
a116cdbcec | ||
|
|
f2d616c98e | ||
|
|
42cbd1777d | ||
|
|
ebf375aac0 | ||
|
|
1f9050267e | ||
|
|
d7f9707a15 | ||
|
|
ab589ee3ed | ||
|
|
c84ec0361f | ||
|
|
47d2f8968a | ||
|
|
019c480bcc | ||
|
|
547c6d3d59 | ||
|
|
b5ebf8b76a | ||
|
|
c690e328f2 | ||
|
|
cbb92c1a95 | ||
|
|
beb41997c9 | ||
|
|
755a6faf11 | ||
|
|
021f8350a3 | ||
|
|
76583dcd2f | ||
|
|
bf033239a7 | ||
|
|
eb37fccd37 | ||
|
|
d04ad45331 | ||
|
|
db157b8ca7 | ||
|
|
68f277bb20 | ||
|
|
4de8f42664 | ||
|
|
4f11855935 | ||
|
|
2b9a5fcc32 | ||
|
|
224948d1f2 | ||
|
|
36f2812d5a | ||
|
|
be06aa2b31 | ||
|
|
41f8e3aba2 | ||
|
|
093c0df897 | ||
|
|
37afc7dc8a | ||
|
|
efbf354960 | ||
|
|
5e39fe0d80 | ||
|
|
47328dc659 | ||
|
|
addeef50ba | ||
|
|
ad338cc5b5 | ||
|
|
202bc8201e | ||
|
|
5ff99de405 | ||
|
|
86ebe2cf9c | ||
|
|
facf0b399c | ||
|
|
33db7b0bcb | ||
|
|
663d07bca1 | ||
|
|
ba04e4997f | ||
|
|
c4fee1b658 | ||
|
|
99b92a15bb | ||
|
|
b076ab5b57 | ||
|
|
687759f75d | ||
|
|
9eaac7f3af | ||
|
|
4c24e00cfc | ||
|
|
beb17011b0 | ||
|
|
e882bf55bc | ||
|
|
3a3016adb6 | ||
|
|
1e8b68153a | ||
|
|
9335cf65fb | ||
|
|
83f35256ae | ||
|
|
4283333948 | ||
|
|
b8f902796b | ||
|
|
8f99ab295c | ||
|
|
882310e268 | ||
|
|
56bce95214 | ||
|
|
c13ecbec29 | ||
|
|
0ffaaa6e73 | ||
|
|
75eff3adea | ||
|
|
bf5f80476c | ||
|
|
9aaf0fbb2f | ||
|
|
8f01ef7953 | ||
|
|
da1d087452 | ||
|
|
e16bc7e882 | ||
|
|
fe9bdd4811 | ||
|
|
17b6f3f6d6 | ||
|
|
90a6baf0ee | ||
|
|
f0e73d0e72 | ||
|
|
a762882f1c | ||
|
|
4c1bc59236 | ||
|
|
f2962083f8 | ||
|
|
a0b22a5bcf | ||
|
|
dcf393354c | ||
|
|
5f771656e3 | ||
|
|
f376aab793 | ||
|
|
3c96464217 | ||
|
|
c9892833a1 | ||
|
|
127c98affc | ||
|
|
8687a772f5 | ||
|
|
b1162b14d4 | ||
|
|
8a8ee35707 | ||
|
|
5e109a3665 | ||
|
|
11db478430 | ||
|
|
a85377014d | ||
|
|
3aea86234d | ||
|
|
916ec6ed6b | ||
|
|
9dca6ba539 | ||
|
|
0ebb89f561 | ||
|
|
e237867e24 | ||
|
|
78fa44fd9a | ||
|
|
d615fa3b93 | ||
|
|
ce134dc332 | ||
|
|
a56e4dc752 | ||
|
|
d221b4aa29 | ||
|
|
d2cba6ad2f | ||
|
|
84b3c30b52 | ||
|
|
68eeec19a8 | ||
|
|
c6d1528a2e | ||
|
|
50a6b256b8 | ||
|
|
bbba1fe477 | ||
|
|
46b827da6b | ||
|
|
5e8c28a30a | ||
|
|
e5d3903164 | ||
|
|
23975c9c9e | ||
|
|
1e0dab8355 | ||
|
|
5f4c10ffd5 | ||
|
|
6f3d2b4b56 | ||
|
|
fea8ace844 | ||
|
|
6633d9262c | ||
|
|
7d54137140 | ||
|
|
2fcda6f248 |
1
MANIFEST.in
Normal file
1
MANIFEST.in
Normal file
@@ -0,0 +1 @@
|
||||
graft tests/fixtures
|
||||
611
README.md
611
README.md
@@ -1,10 +1,9 @@
|
||||
# JC
|
||||
JSON CLI output utility
|
||||
|
||||
`jc` is used to JSONify the output of many standard linux cli tools for easier parsing in scripts. See the **Parsers** section for supported commands.
|
||||
`jc` is used to JSONify the output of many standard linux cli tools and file types for easier parsing in scripts. See the **Parsers** section for supported commands.
|
||||
|
||||
This allows further command line processing of output with tools like `jq` simply by piping commands:
|
||||
|
||||
```
|
||||
$ ls -l /usr/bin | jc --ls | jq '.[] | select(.size > 50000000)'
|
||||
{
|
||||
@@ -17,7 +16,19 @@ $ ls -l /usr/bin | jc --ls | jq '.[] | select(.size > 50000000)'
|
||||
"date": "Aug 14 19:41"
|
||||
}
|
||||
```
|
||||
|
||||
or using the alternative "magic" syntax:
|
||||
```
|
||||
$ jc ls -l /usr/bin | jq '.[] | select(.size > 50000000)'
|
||||
{
|
||||
"filename": "docker",
|
||||
"flags": "-rwxr-xr-x",
|
||||
"links": 1,
|
||||
"owner": "root",
|
||||
"group": "root",
|
||||
"size": 68677120,
|
||||
"date": "Aug 14 19:41"
|
||||
}
|
||||
```
|
||||
The `jc` parsers can also be used as python modules. In this case the output will be a python dictionary instead of JSON:
|
||||
```
|
||||
>>> import jc.parsers.ls
|
||||
@@ -44,13 +55,13 @@ The `jc` parsers can also be used as python modules. In this case the output wil
|
||||
{'filename': 'echo', 'flags': '-rwxr-xr-x', 'links': 1, 'owner': 'root', 'group': 'wheel', 'size': 18128,
|
||||
'date': 'May 3 22:26'}]
|
||||
```
|
||||
Two representations of the data are possible. The default representation uses a strict schema per parser and converts known numbers to int/float JSON values. Certain known values of None are converted to JSON Null, known boolean values are converted, and, in some cases, additional semantic context fields are added.
|
||||
Two representations of the data are possible. The default representation uses a strict schema per parser and converts known numbers to int/float JSON values. Certain known values of `None` are converted to JSON `null`, known boolean values are converted, and, in some cases, additional semantic context fields are added.
|
||||
|
||||
To access the raw, pre-processed JSON, use the `-r` cli option or the `raw=True` function parameter in `parse()`.
|
||||
|
||||
Schemas for each parser can be found in the `docs/parsers` folder.
|
||||
Schemas for each parser can be found in the [`docs/parsers`](https://github.com/kellyjonbrazil/jc/tree/dev/docs/parsers) folder.
|
||||
|
||||
> ***Note:** Due to the introduction of schemas in version `1.5.1` the output of some parsers will be different than in versions `1.1.1` and below. Now that schemas are defined, the output will be stable for future versions. You can still get similar output to prior versions with the `-r` or `raw=true` options. Though the goal is to keep all output stable, raw output is not guaranteed to stay the same in future releases.*
|
||||
For more information on the motivations for this project, please see my [blog post](https://blog.kellybrazil.com/2019/11/26/bringing-the-unix-philosophy-to-the-21st-century/).
|
||||
|
||||
## Installation
|
||||
```
|
||||
@@ -58,43 +69,61 @@ $ pip3 install --upgrade jc
|
||||
```
|
||||
|
||||
## Usage
|
||||
`jc` accepts piped input from `STDIN` and outputs a JSON representation of the previous command's output to `STDOUT`.
|
||||
```
|
||||
jc PARSER [OPTIONS]
|
||||
COMMAND | jc PARSER [OPTIONS]
|
||||
```
|
||||
|
||||
`jc` accepts piped input from `STDIN` and outputs a JSON representation of the previous command's output to `STDOUT`. The JSON output can be compact or pretty formatted.
|
||||
or
|
||||
```
|
||||
COMMAND | jc [OPTIONS] PARSER
|
||||
```
|
||||
Alternatively, the "magic" syntax can be used by prepending `jc` to the command to be converted. Options can be passed to `jc` immediately before the command is given. (Note: command aliases are not supported)
|
||||
```
|
||||
jc [OPTIONS] COMMAND
|
||||
```
|
||||
The JSON output can be compact (default) or pretty formatted with the `-p` option.
|
||||
|
||||
### Parsers
|
||||
- `--arp` enables the `arp` parser
|
||||
- `--df` enables the `df` parser
|
||||
- `--dig` enables the `dig` parser
|
||||
- `--env` enables the `env` parser
|
||||
- `--free` enables the `free` parser
|
||||
- `--arp` enables the `arp` command parser
|
||||
- `--crontab` enables the `crontab` command and file parser
|
||||
- `--crontab-u` enables the `crontab` file parser with user support
|
||||
- `--df` enables the `df` command parser
|
||||
- `--dig` enables the `dig` command parser
|
||||
- `--du` enables the `du` command parser
|
||||
- `--env` enables the `env` command parser
|
||||
- `--free` enables the `free` command parser
|
||||
- `--fstab` enables the `/etc/fstab` file parser
|
||||
- `--history` enables the `history` parser
|
||||
- `--history` enables the `history` command parser
|
||||
- `--hosts` enables the `/etc/hosts` file parser
|
||||
- `--ifconfig` enables the `ifconfig` parser
|
||||
- `--iptables` enables the `iptables` parser
|
||||
- `--jobs` enables the `jobs` parser
|
||||
- `--ls` enables the `ls` parser
|
||||
- `--lsblk` enables the `lsblk` parser
|
||||
- `--lsmod` enables the `lsmod` parser
|
||||
- `--lsof` enables the `lsof` parser
|
||||
- `--mount` enables the `mount` parser
|
||||
- `--netstat` enables the `netstat` parser
|
||||
- `--ps` enables the `ps` parser
|
||||
- `--route` enables the `route` parser
|
||||
- `--ss` enables the `ss` parser
|
||||
- `--stat` enables the `stat` parser
|
||||
- `--systemctl` enables the `systemctl` parser
|
||||
- `--systemctl-lj` enables the `systemctl list-jobs` parser
|
||||
- `--systemctl-ls` enables the `systemctl list-sockets` parser
|
||||
- `--systemctl-luf` enables the `systemctl list-unit-files` parser
|
||||
- `--uname` enables the `uname -a` parser
|
||||
- `--uptime` enables the `uptime` parser
|
||||
- `--w` enables the `w` parser
|
||||
- `--id` enables the `id` command parser
|
||||
- `--ifconfig` enables the `ifconfig` command parser
|
||||
- `--ini` enables the `INI` file parser
|
||||
- `--iptables` enables the `iptables` command parser
|
||||
- `--jobs` enables the `jobs` command parser
|
||||
- `--ls` enables the `ls` command parser
|
||||
- `--lsblk` enables the `lsblk` command parser
|
||||
- `--lsmod` enables the `lsmod` command parser
|
||||
- `--lsof` enables the `lsof` command parser
|
||||
- `--mount` enables the `mount` command parser
|
||||
- `--netstat` enables the `netstat` command parser
|
||||
- `--pip-list` enables the `pip list` command parser
|
||||
- `--pip-show` enables the `pip show` command parser
|
||||
- `--ps` enables the `ps` command parser
|
||||
- `--route` enables the `route` command parser
|
||||
- `--ss` enables the `ss` command parser
|
||||
- `--stat` enables the `stat` command parser
|
||||
- `--systemctl` enables the `systemctl` command parser
|
||||
- `--systemctl-lj` enables the `systemctl list-jobs` command parser
|
||||
- `--systemctl-ls` enables the `systemctl list-sockets` command parser
|
||||
- `--systemctl-luf` enables the `systemctl list-unit-files` command parser
|
||||
- `--uname` enables the `uname -a` command parser
|
||||
- `--uptime` enables the `uptime` command parser
|
||||
- `--w` enables the `w` command parser
|
||||
- `--xml` enables the `XML` file parser
|
||||
- `--yaml` enables the `YAML` file parser
|
||||
|
||||
### Options
|
||||
- `-a` about `jc`. Prints information about `jc` and the parsers (in JSON, of course!)
|
||||
- `-d` debug mode. Prints trace messages if parsing issues encountered
|
||||
- `-p` pretty format the JSON output
|
||||
- `-q` quiet mode. Suppresses warning messages
|
||||
@@ -103,7 +132,7 @@ jc PARSER [OPTIONS]
|
||||
## Examples
|
||||
### arp
|
||||
```
|
||||
$ arp | jc --arp -p
|
||||
$ arp | jc --arp -p # or: jc -p arp
|
||||
[
|
||||
{
|
||||
"address": "gateway",
|
||||
@@ -129,7 +158,7 @@ $ arp | jc --arp -p
|
||||
]
|
||||
```
|
||||
```
|
||||
$ arp -a | jc --arp -p
|
||||
$ arp -a | jc --arp -p # or: jc -p arp -a
|
||||
[
|
||||
{
|
||||
"name": null,
|
||||
@@ -154,13 +183,160 @@ $ arp -a | jc --arp -p
|
||||
}
|
||||
]
|
||||
```
|
||||
### crontab
|
||||
```
|
||||
$ cat /etc/crontab | jc --crontab -p # or: jc -p crontab -l
|
||||
{
|
||||
"variables": [
|
||||
{
|
||||
"name": "MAILTO",
|
||||
"value": "root"
|
||||
},
|
||||
{
|
||||
"name": "PATH",
|
||||
"value": "/sbin:/bin:/usr/sbin:/usr/bin"
|
||||
},
|
||||
{
|
||||
"name": "SHELL",
|
||||
"value": "/bin/bash"
|
||||
}
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
"minute": [
|
||||
"5"
|
||||
],
|
||||
"hour": [
|
||||
"10-11",
|
||||
"22"
|
||||
],
|
||||
"day_of_month": [
|
||||
"*"
|
||||
],
|
||||
"month": [
|
||||
"*"
|
||||
],
|
||||
"day_of_week": [
|
||||
"*"
|
||||
],
|
||||
"command": "/var/www/devdaily.com/bin/mk-new-links.php"
|
||||
},
|
||||
{
|
||||
"minute": [
|
||||
"30"
|
||||
],
|
||||
"hour": [
|
||||
"4/2"
|
||||
],
|
||||
"day_of_month": [
|
||||
"*"
|
||||
],
|
||||
"month": [
|
||||
"*"
|
||||
],
|
||||
"day_of_week": [
|
||||
"*"
|
||||
],
|
||||
"command": "/var/www/devdaily.com/bin/create-all-backups.sh"
|
||||
},
|
||||
{
|
||||
"occurrence": "yearly",
|
||||
"command": "/home/maverick/bin/annual-maintenance"
|
||||
},
|
||||
{
|
||||
"occurrence": "reboot",
|
||||
"command": "/home/cleanup"
|
||||
},
|
||||
{
|
||||
"occurrence": "monthly",
|
||||
"command": "/home/maverick/bin/tape-backup"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### crontab-u (with user support)
|
||||
```
|
||||
$ cat /etc/crontab | jc --crontab-u -p
|
||||
{
|
||||
"variables": [
|
||||
{
|
||||
"name": "MAILTO",
|
||||
"value": "root"
|
||||
},
|
||||
{
|
||||
"name": "PATH",
|
||||
"value": "/sbin:/bin:/usr/sbin:/usr/bin"
|
||||
},
|
||||
{
|
||||
"name": "SHELL",
|
||||
"value": "/bin/bash"
|
||||
}
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
"minute": [
|
||||
"5"
|
||||
],
|
||||
"hour": [
|
||||
"10-11",
|
||||
"22"
|
||||
],
|
||||
"day_of_month": [
|
||||
"*"
|
||||
],
|
||||
"month": [
|
||||
"*"
|
||||
],
|
||||
"day_of_week": [
|
||||
"*"
|
||||
],
|
||||
"user": "root",
|
||||
"command": "/var/www/devdaily.com/bin/mk-new-links.php"
|
||||
},
|
||||
{
|
||||
"minute": [
|
||||
"30"
|
||||
],
|
||||
"hour": [
|
||||
"4/2"
|
||||
],
|
||||
"day_of_month": [
|
||||
"*"
|
||||
],
|
||||
"month": [
|
||||
"*"
|
||||
],
|
||||
"day_of_week": [
|
||||
"*"
|
||||
],
|
||||
"user": "root",
|
||||
"command": "/var/www/devdaily.com/bin/create-all-backups.sh"
|
||||
},
|
||||
{
|
||||
"occurrence": "yearly",
|
||||
"user": "root",
|
||||
"command": "/home/maverick/bin/annual-maintenance"
|
||||
},
|
||||
{
|
||||
"occurrence": "reboot",
|
||||
"user": "root",
|
||||
"command": "/home/cleanup"
|
||||
},
|
||||
{
|
||||
"occurrence": "monthly",
|
||||
"user": "root",
|
||||
"command": "/home/maverick/bin/tape-backup"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### df
|
||||
```
|
||||
$ df | jc --df -p
|
||||
$ df | jc --df -p # or: jc -p df
|
||||
[
|
||||
{
|
||||
"filesystem": "devtmpfs",
|
||||
"1k-blocks": 1918816,
|
||||
"1k_blocks": 1918816,
|
||||
"used": 0,
|
||||
"available": 1918816,
|
||||
"use_percent": 0,
|
||||
@@ -168,7 +344,7 @@ $ df | jc --df -p
|
||||
},
|
||||
{
|
||||
"filesystem": "tmpfs",
|
||||
"1k-blocks": 1930664,
|
||||
"1k_blocks": 1930664,
|
||||
"used": 0,
|
||||
"available": 1930664,
|
||||
"use_percent": 0,
|
||||
@@ -179,7 +355,7 @@ $ df | jc --df -p
|
||||
```
|
||||
### dig
|
||||
```
|
||||
$ dig cnn.com www.cnn.com @205.251.194.64 | jc --dig -p
|
||||
$ dig cnn.com www.cnn.com @205.251.194.64 | jc --dig -p # or: jc -p dig cnn.com www.cnn.com @205.251.194.64
|
||||
[
|
||||
{
|
||||
"id": 5509,
|
||||
@@ -299,7 +475,7 @@ $ dig cnn.com www.cnn.com @205.251.194.64 | jc --dig -p
|
||||
]
|
||||
```
|
||||
```
|
||||
$ dig -x 1.1.1.1 | jc --dig -p
|
||||
$ dig -x 1.1.1.1 | jc --dig -p # or: jc -p dig -x 1.1.1.1
|
||||
[
|
||||
{
|
||||
"id": 50324,
|
||||
@@ -335,9 +511,40 @@ $ dig -x 1.1.1.1 | jc --dig -p
|
||||
}
|
||||
]
|
||||
```
|
||||
### du
|
||||
```
|
||||
$ du /usr | jc --du -p # or: jc -p du /usr
|
||||
[
|
||||
{
|
||||
"size": 104608,
|
||||
"name": "/usr/bin"
|
||||
},
|
||||
{
|
||||
"size": 56,
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/_CodeSignature"
|
||||
},
|
||||
{
|
||||
"size": 0,
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/usr/local/standalone"
|
||||
},
|
||||
{
|
||||
"size": 0,
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/usr/local"
|
||||
},
|
||||
{
|
||||
"size": 0,
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/usr"
|
||||
},
|
||||
{
|
||||
"size": 1008,
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/dfu"
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### env
|
||||
```
|
||||
$ env | jc --env -p
|
||||
$ env | jc --env -p # or: jc -p env
|
||||
[
|
||||
{
|
||||
"name": "XDG_SESSION_ID",
|
||||
@@ -364,7 +571,7 @@ $ env | jc --env -p
|
||||
```
|
||||
### free
|
||||
```
|
||||
$ free | jc --free -p
|
||||
$ free | jc --free -p # or: jc -p free
|
||||
[
|
||||
{
|
||||
"type": "Mem",
|
||||
@@ -383,7 +590,7 @@ $ free | jc --free -p
|
||||
}
|
||||
]
|
||||
```
|
||||
### /etc/fstab
|
||||
### /etc/fstab file
|
||||
```
|
||||
$ cat /etc/fstab | jc --fstab -p
|
||||
[
|
||||
@@ -418,25 +625,25 @@ $ cat /etc/fstab | jc --fstab -p
|
||||
$ history | jc --history -p
|
||||
[
|
||||
{
|
||||
"line": "118",
|
||||
"line": 118,
|
||||
"command": "sleep 100"
|
||||
},
|
||||
{
|
||||
"line": "119",
|
||||
"line": 119,
|
||||
"command": "ls /bin"
|
||||
},
|
||||
{
|
||||
"line": "120",
|
||||
"line": 120,
|
||||
"command": "echo \"hello\""
|
||||
},
|
||||
{
|
||||
"line": "121",
|
||||
"line": 121,
|
||||
"command": "docker images"
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### /etc/hosts
|
||||
### /etc/hosts file
|
||||
```
|
||||
$ cat /etc/hosts | jc --hosts -p
|
||||
[
|
||||
@@ -485,29 +692,66 @@ $ cat /etc/hosts | jc --hosts -p
|
||||
}
|
||||
]
|
||||
```
|
||||
### id
|
||||
```
|
||||
$ id | jc --id -p # or: jc -p id
|
||||
{
|
||||
"uid": {
|
||||
"id": 1000,
|
||||
"name": "joeuser"
|
||||
},
|
||||
"gid": {
|
||||
"id": 1000,
|
||||
"name": "joeuser"
|
||||
},
|
||||
"groups": [
|
||||
{
|
||||
"id": 1000,
|
||||
"name": "joeuser"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "wheel"
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"user": "unconfined_u",
|
||||
"role": "unconfined_r",
|
||||
"type": "unconfined_t",
|
||||
"level": "s0-s0:c0.c1023"
|
||||
}
|
||||
}
|
||||
```
|
||||
### ifconfig
|
||||
```
|
||||
$ ifconfig | jc --ifconfig -p
|
||||
$ ifconfig | jc --ifconfig -p # or: jc -p ifconfig
|
||||
[
|
||||
{
|
||||
"name": "ens33",
|
||||
"flags": 4163,
|
||||
"state": "UP,BROADCAST,RUNNING,MULTICAST",
|
||||
"state": [
|
||||
"UP",
|
||||
"BROADCAST",
|
||||
"RUNNING",
|
||||
"MULTICAST"
|
||||
],
|
||||
"mtu": 1500,
|
||||
"ipv4_addr": "192.168.71.138",
|
||||
"ipv4_addr": "192.168.71.137",
|
||||
"ipv4_mask": "255.255.255.0",
|
||||
"ipv4_bcast": "192.168.71.255",
|
||||
"ipv6_addr": "fe80::c1cb:715d:bc3e:b8a0",
|
||||
"ipv6_mask": 64,
|
||||
"ipv6_scope": "link",
|
||||
"ipv6_scope": "0x20",
|
||||
"mac_addr": "00:0c:29:3b:58:0e",
|
||||
"type": "Ethernet",
|
||||
"rx_packets": 6374,
|
||||
"rx_packets": 8061,
|
||||
"rx_bytes": 1514413,
|
||||
"rx_errors": 0,
|
||||
"rx_dropped": 0,
|
||||
"rx_overruns": 0,
|
||||
"rx_frame": 0,
|
||||
"tx_packets": 3707,
|
||||
"tx_packets": 4502,
|
||||
"tx_bytes": 866622,
|
||||
"tx_errors": 0,
|
||||
"tx_dropped": 0,
|
||||
"tx_overruns": 0,
|
||||
@@ -518,22 +762,28 @@ $ ifconfig | jc --ifconfig -p
|
||||
{
|
||||
"name": "lo",
|
||||
"flags": 73,
|
||||
"state": "UP,LOOPBACK,RUNNING",
|
||||
"state": [
|
||||
"UP",
|
||||
"LOOPBACK",
|
||||
"RUNNING"
|
||||
],
|
||||
"mtu": 65536,
|
||||
"ipv4_addr": "127.0.0.1",
|
||||
"ipv4_mask": "255.0.0.0",
|
||||
"ipv4_bcast": null,
|
||||
"ipv6_addr": "::1",
|
||||
"ipv6_mask": 128,
|
||||
"ipv6_scope": "host",
|
||||
"ipv6_scope": "0x10",
|
||||
"mac_addr": null,
|
||||
"type": "Local Loopback",
|
||||
"rx_packets": 81,
|
||||
"rx_packets": 73,
|
||||
"rx_bytes": 6009,
|
||||
"rx_errors": 0,
|
||||
"rx_dropped": 0,
|
||||
"rx_overruns": 0,
|
||||
"rx_frame": 0,
|
||||
"tx_packets": 81,
|
||||
"tx_packets": 73,
|
||||
"tx_bytes": 6009,
|
||||
"tx_errors": 0,
|
||||
"tx_dropped": 0,
|
||||
"tx_overruns": 0,
|
||||
@@ -543,9 +793,43 @@ $ ifconfig | jc --ifconfig -p
|
||||
}
|
||||
]
|
||||
```
|
||||
### INI files
|
||||
```
|
||||
$ cat example.ini
|
||||
[DEFAULT]
|
||||
ServerAliveInterval = 45
|
||||
Compression = yes
|
||||
CompressionLevel = 9
|
||||
ForwardX11 = yes
|
||||
|
||||
[bitbucket.org]
|
||||
User = hg
|
||||
|
||||
[topsecret.server.com]
|
||||
Port = 50022
|
||||
ForwardX11 = no
|
||||
|
||||
$ cat example.ini | jc --ini -p
|
||||
{
|
||||
"bitbucket.org": {
|
||||
"serveraliveinterval": "45",
|
||||
"compression": "yes",
|
||||
"compressionlevel": "9",
|
||||
"forwardx11": "yes",
|
||||
"user": "hg"
|
||||
},
|
||||
"topsecret.server.com": {
|
||||
"serveraliveinterval": "45",
|
||||
"compression": "yes",
|
||||
"compressionlevel": "9",
|
||||
"forwardx11": "no",
|
||||
"port": "50022"
|
||||
}
|
||||
}
|
||||
```
|
||||
### iptables
|
||||
```
|
||||
$ sudo iptables --line-numbers -v -L -t nat | jc --iptables -p
|
||||
$ sudo iptables --line-numbers -v -L -t nat | jc --iptables -p # or: sudo jc -p iptables --line-numbers -v -L -t nat
|
||||
[
|
||||
{
|
||||
"chain": "PREROUTING",
|
||||
@@ -606,7 +890,7 @@ $ sudo iptables --line-numbers -v -L -t nat | jc --iptables -p
|
||||
```
|
||||
### jobs
|
||||
```
|
||||
$ jobs -l | jc --jobs -p
|
||||
$ jobs -l | jc --jobs -p # or: jc -p jobs
|
||||
[
|
||||
{
|
||||
"job_number": 1,
|
||||
@@ -638,7 +922,7 @@ $ jobs -l | jc --jobs -p
|
||||
```
|
||||
### ls
|
||||
```
|
||||
$ ls -l /usr/bin | jc --ls -p
|
||||
$ ls -l /usr/bin | jc --ls -p # or: jc -p ls -l /usr/bin
|
||||
[
|
||||
{
|
||||
"filename": "apropos",
|
||||
@@ -673,7 +957,7 @@ $ ls -l /usr/bin | jc --ls -p
|
||||
```
|
||||
### lsblk
|
||||
```
|
||||
$ lsblk | jc --lsblk -p
|
||||
$ lsblk | jc --lsblk -p # or: jc -p lsblk
|
||||
[
|
||||
{
|
||||
"name": "sda",
|
||||
@@ -698,7 +982,7 @@ $ lsblk | jc --lsblk -p
|
||||
```
|
||||
### lsmod
|
||||
```
|
||||
$ lsmod | jc --lsmod -p
|
||||
$ lsmod | jc --lsmod -p # or: jc -p lsmod
|
||||
[
|
||||
...
|
||||
{
|
||||
@@ -745,7 +1029,7 @@ $ lsmod | jc --lsmod -p
|
||||
```
|
||||
### lsof
|
||||
```
|
||||
$ sudo lsof | jc --lsof -p
|
||||
$ sudo lsof | jc --lsof -p # or: sudo jc -p lsof
|
||||
[
|
||||
{
|
||||
"command": "systemd",
|
||||
@@ -788,7 +1072,7 @@ $ sudo lsof | jc --lsof -p
|
||||
```
|
||||
### mount
|
||||
```
|
||||
$ mount | jc --mount -p
|
||||
$ mount | jc --mount -p # or: jc -p mount
|
||||
[
|
||||
{
|
||||
"filesystem": "sysfs",
|
||||
@@ -832,7 +1116,7 @@ $ mount | jc --mount -p
|
||||
```
|
||||
### netstat
|
||||
```
|
||||
$ sudo netstat -apee | jc --netstat -p
|
||||
$ sudo netstat -apee | jc --netstat -p # or: sudo jc -p netstat -apee
|
||||
[
|
||||
{
|
||||
"proto": "tcp",
|
||||
@@ -982,9 +1266,59 @@ $ sudo netstat -apee | jc --netstat -p
|
||||
...
|
||||
]
|
||||
```
|
||||
### pip list
|
||||
```
|
||||
$ pip list | jc --pip-list -p # or: jc -p pip list # or: jc -p pip3 list
|
||||
[
|
||||
{
|
||||
"package": "ansible",
|
||||
"version": "2.8.5"
|
||||
},
|
||||
{
|
||||
"package": "antlr4-python3-runtime",
|
||||
"version": "4.7.2"
|
||||
},
|
||||
{
|
||||
"package": "asn1crypto",
|
||||
"version": "0.24.0"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
```
|
||||
### pip show
|
||||
```
|
||||
$ pip show wrapt wheel | jc --pip-show -p # or: jc -p pip show wrapt wheel # or: jc -p pip3 show wrapt wheel
|
||||
[
|
||||
{
|
||||
"name": "wrapt",
|
||||
"version": "1.11.2",
|
||||
"summary": "Module for decorators, wrappers and monkey patching.",
|
||||
"home_page": "https://github.com/GrahamDumpleton/wrapt",
|
||||
"author": "Graham Dumpleton",
|
||||
"author_email": "Graham.Dumpleton@gmail.com",
|
||||
"license": "BSD",
|
||||
"location": "/usr/local/lib/python3.7/site-packages",
|
||||
"requires": null,
|
||||
"required_by": "astroid"
|
||||
},
|
||||
{
|
||||
"name": "wheel",
|
||||
"version": "0.33.4",
|
||||
"summary": "A built-package format for Python.",
|
||||
"home_page": "https://github.com/pypa/wheel",
|
||||
"author": "Daniel Holth",
|
||||
"author_email": "dholth@fastmail.fm",
|
||||
"license": "MIT",
|
||||
"location": "/usr/local/lib/python3.7/site-packages",
|
||||
"requires": null,
|
||||
"required_by": null
|
||||
}
|
||||
]
|
||||
```
|
||||
### ps
|
||||
```
|
||||
$ ps -ef | jc --ps -p
|
||||
$ ps -ef | jc --ps -p # or: jc -p ps -ef
|
||||
[
|
||||
{
|
||||
"uid": "root",
|
||||
@@ -1020,7 +1354,7 @@ $ ps -ef | jc --ps -p
|
||||
]
|
||||
```
|
||||
```
|
||||
$ ps axu | jc --ps -p
|
||||
$ ps axu | jc --ps -p # or: jc -p ps axu
|
||||
[
|
||||
{
|
||||
"user": "root",
|
||||
@@ -1066,7 +1400,7 @@ $ ps axu | jc --ps -p
|
||||
```
|
||||
### route
|
||||
```
|
||||
$ route -ee | jc --route -p
|
||||
$ route -ee | jc --route -p # or: jc -p route -ee
|
||||
[
|
||||
{
|
||||
"destination": "default",
|
||||
@@ -1111,7 +1445,7 @@ $ route -ee | jc --route -p
|
||||
```
|
||||
### ss
|
||||
```
|
||||
$ sudo ss -a | jc --ss -p
|
||||
$ sudo ss -a | jc --ss -p # or: sudo jc -p ss -a
|
||||
[
|
||||
{
|
||||
"netid": "nl",
|
||||
@@ -1230,7 +1564,7 @@ $ sudo ss -a | jc --ss -p
|
||||
```
|
||||
### stat
|
||||
```
|
||||
$ stat /bin/* | jc --stat -p
|
||||
$ stat /bin/* | jc --stat -p # or: jc -p stat /bin/*
|
||||
[
|
||||
{
|
||||
"file": "/bin/bash",
|
||||
@@ -1277,7 +1611,7 @@ $ stat /bin/* | jc --stat -p
|
||||
```
|
||||
### systemctl
|
||||
```
|
||||
$ systemctl -a | jc --systemctl -p
|
||||
$ systemctl -a | jc --systemctl -p # or: jc -p systemctl -a
|
||||
[
|
||||
{
|
||||
"unit": "proc-sys-fs-binfmt_misc.automount",
|
||||
@@ -1305,7 +1639,7 @@ $ systemctl -a | jc --systemctl -p
|
||||
```
|
||||
### systemctl list-jobs
|
||||
```
|
||||
$ systemctl list-jobs| jc --systemctl-lj -p
|
||||
$ systemctl list-jobs | jc --systemctl-lj -p # or: jc -p systemctl list-jobs
|
||||
[
|
||||
{
|
||||
"job": 3543,
|
||||
@@ -1329,7 +1663,7 @@ $ systemctl list-jobs| jc --systemctl-lj -p
|
||||
```
|
||||
### systemctl list-sockets
|
||||
```
|
||||
$ systemctl list-sockets | jc --systemctl-ls -p
|
||||
$ systemctl list-sockets | jc --systemctl-ls -p # or: jc -p systemctl list-sockets
|
||||
[
|
||||
{
|
||||
"listen": "/dev/log",
|
||||
@@ -1351,7 +1685,7 @@ $ systemctl list-sockets | jc --systemctl-ls -p
|
||||
```
|
||||
### systemctl list-unit-files
|
||||
```
|
||||
$ systemctl list-unit-files | jc --systemctl-luf -p
|
||||
$ systemctl list-unit-files | jc --systemctl-luf -p # or: jc -p systemctl list-unit-files
|
||||
[
|
||||
{
|
||||
"unit_file": "proc-sys-fs-binfmt_misc.automount",
|
||||
@@ -1370,7 +1704,7 @@ $ systemctl list-unit-files | jc --systemctl-luf -p
|
||||
```
|
||||
### uname -a
|
||||
```
|
||||
$ uname -a | jc --uname -p
|
||||
$ uname -a | jc --uname -p # or: jc -p uname -a
|
||||
{
|
||||
"kernel_name": "Linux",
|
||||
"node_name": "user-ubuntu",
|
||||
@@ -1384,7 +1718,7 @@ $ uname -a | jc --uname -p
|
||||
```
|
||||
### uptime
|
||||
```
|
||||
$ uptime | jc --uptime -p
|
||||
$ uptime | jc --uptime -p # or: jc -p uptime
|
||||
{
|
||||
"time": "11:30:44",
|
||||
"uptime": "1 day, 21:17",
|
||||
@@ -1396,7 +1730,7 @@ $ uptime | jc --uptime -p
|
||||
```
|
||||
### w
|
||||
```
|
||||
$ w | jc --w -p
|
||||
$ w | jc --w -p # or: jc -p w
|
||||
[
|
||||
{
|
||||
"user": "root",
|
||||
@@ -1430,11 +1764,112 @@ $ w | jc --w -p
|
||||
}
|
||||
]
|
||||
```
|
||||
### XML files
|
||||
```
|
||||
$ cat cd_catalog.xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CATALOG>
|
||||
<CD>
|
||||
<TITLE>Empire Burlesque</TITLE>
|
||||
<ARTIST>Bob Dylan</ARTIST>
|
||||
<COUNTRY>USA</COUNTRY>
|
||||
<COMPANY>Columbia</COMPANY>
|
||||
<PRICE>10.90</PRICE>
|
||||
<YEAR>1985</YEAR>
|
||||
</CD>
|
||||
<CD>
|
||||
<TITLE>Hide your heart</TITLE>
|
||||
<ARTIST>Bonnie Tyler</ARTIST>
|
||||
<COUNTRY>UK</COUNTRY>
|
||||
<COMPANY>CBS Records</COMPANY>
|
||||
<PRICE>9.90</PRICE>
|
||||
<YEAR>1988</YEAR>
|
||||
</CD>
|
||||
...
|
||||
|
||||
$ cat cd_catalog.xml | jc --xml -p
|
||||
{
|
||||
"CATALOG": {
|
||||
"CD": [
|
||||
{
|
||||
"TITLE": "Empire Burlesque",
|
||||
"ARTIST": "Bob Dylan",
|
||||
"COUNTRY": "USA",
|
||||
"COMPANY": "Columbia",
|
||||
"PRICE": "10.90",
|
||||
"YEAR": "1985"
|
||||
},
|
||||
{
|
||||
"TITLE": "Hide your heart",
|
||||
"ARTIST": "Bonnie Tyler",
|
||||
"COUNTRY": "UK",
|
||||
"COMPANY": "CBS Records",
|
||||
"PRICE": "9.90",
|
||||
"YEAR": "1988"
|
||||
},
|
||||
...
|
||||
}
|
||||
```
|
||||
### YAML files
|
||||
```
|
||||
$ cat istio.yaml
|
||||
apiVersion: "authentication.istio.io/v1alpha1"
|
||||
kind: "Policy"
|
||||
metadata:
|
||||
name: "default"
|
||||
namespace: "default"
|
||||
spec:
|
||||
peers:
|
||||
- mtls: {}
|
||||
---
|
||||
apiVersion: "networking.istio.io/v1alpha3"
|
||||
kind: "DestinationRule"
|
||||
metadata:
|
||||
name: "default"
|
||||
namespace: "default"
|
||||
spec:
|
||||
host: "*.default.svc.cluster.local"
|
||||
trafficPolicy:
|
||||
tls:
|
||||
mode: ISTIO_MUTUAL
|
||||
|
||||
$ cat istio.yaml | jc --yaml -p
|
||||
[
|
||||
{
|
||||
"apiVersion": "authentication.istio.io/v1alpha1",
|
||||
"kind": "Policy",
|
||||
"metadata": {
|
||||
"name": "default",
|
||||
"namespace": "default"
|
||||
},
|
||||
"spec": {
|
||||
"peers": [
|
||||
{
|
||||
"mtls": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "networking.istio.io/v1alpha3",
|
||||
"kind": "DestinationRule",
|
||||
"metadata": {
|
||||
"name": "default",
|
||||
"namespace": "default"
|
||||
},
|
||||
"spec": {
|
||||
"host": "*.default.svc.cluster.local",
|
||||
"trafficPolicy": {
|
||||
"tls": {
|
||||
"mode": "ISTIO_MUTUAL"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
## TODO
|
||||
Future parsers:
|
||||
- nslookup
|
||||
- journalctl
|
||||
- crontab files
|
||||
- /proc files
|
||||
- /sys files
|
||||
|
||||
@@ -1442,7 +1877,10 @@ Future parsers:
|
||||
Feel free to add/improve code or parsers! You can use the `jc/parsers/foo.py` parser as a template and submit your parser with a pull request.
|
||||
|
||||
## Compatibility
|
||||
Some parsers like `ls`, `ps`, `dig`, etc. will work on any platform. Other parsers that are platform-specific will generate a warning message if they are used on an unsupported platform. You may still use a parser on an unsupported platform - for example, you may want to parse a file with linux `lsof` output on an OSX laptop. In that case you can suppress the warning message with the `-q` cli option or the `quiet=True` function parameter in `parse()`:
|
||||
Some parsers like `ls`, `ps`, `dig`, etc. will work on any platform. Other parsers that are platform-specific will generate a warning message if they are used on an unsupported platform. To see all parser information, including compatibility, run `jc -ap`.
|
||||
|
||||
|
||||
You may still use a parser on an unsupported platform - for example, you may want to parse a file with linux `lsof` output on an OSX laptop. In that case you can suppress the warning message with the `-q` cli option or the `quiet=True` function parameter in `parse()`:
|
||||
|
||||
```
|
||||
$ cat lsof.out | jc --lsof -q
|
||||
@@ -1451,7 +1889,12 @@ $ cat lsof.out | jc --lsof -q
|
||||
Tested on:
|
||||
- Centos 7.7
|
||||
- Ubuntu 18.4
|
||||
- OSX 10.11.6
|
||||
- OSX 10.14.6
|
||||
|
||||
## Acknowledgments
|
||||
- `ifconfig-parser` module from https://github.com/KnightWhoSayNi/ifconfig-parser
|
||||
- `xmltodict` module from https://github.com/martinblech/xmltodict by Martín Blech
|
||||
- `ruamel.yaml` library from https://pypi.org/project/ruamel.yaml by Anthon van der Neut
|
||||
- Parsing code from Conor Heine at https://gist.github.com/cahna/43a1a3ff4d075bcd71f9d7120037a501 adapted for some parsers
|
||||
- Excellent constructive feedback from Ilya Sher (https://github.com/ilyash-b)
|
||||
|
||||
1
_config.yml
Normal file
1
_config.yml
Normal file
@@ -0,0 +1 @@
|
||||
theme: jekyll-theme-cayman
|
||||
@@ -1,5 +1,39 @@
|
||||
jc changelog
|
||||
|
||||
20200219 v1.7.4
|
||||
- Updated ls parser to support multiple directories, globbing, and -R (recursive)
|
||||
|
||||
20200211 v1.7.3
|
||||
- Add alternative 'magic' syntax: e.g. `jc ls -al`
|
||||
- Options can now be condensed (e.g. -prq is equivalant to -p -r -q)
|
||||
|
||||
20200208 v1.7.2
|
||||
- Include test fixtures in wheel and sdist
|
||||
|
||||
20200205 v1.7.1
|
||||
- Add YAML file parser
|
||||
- Add INI file parser
|
||||
- Add XML file parser
|
||||
- Add id parser (tested on linux and OSX)
|
||||
- Add crontab file parser with user support (tested on linux)
|
||||
- Add __version__ variable to parser modules
|
||||
- Add exit code on error
|
||||
- Updated history parser to output "line" as an integer
|
||||
- Updated compatibility list for some parsers
|
||||
- Bugfix in crontab file parser: header insertion was clobbering first row
|
||||
- Just-in-time loading of parser modules instead of loading all at start
|
||||
|
||||
20191217 v1.6.1
|
||||
- Add du parser (tested on linux and OSX)
|
||||
- Add crontab parser (tested on linux and OSX)
|
||||
- Add pip list parser (tested on linux and OSX)
|
||||
- Add pip show parser (tested on linux and OSX)
|
||||
- Add OSX support for the ifconfig, arp, df, mount, and uname parsers
|
||||
- Add tests for ls, dig, ps, w, uptime on OSX
|
||||
- Add about option
|
||||
- Add universal parsers to refactor repetitive code
|
||||
- Updated ifconfig parser to output 'state' as an array
|
||||
|
||||
20191117 v1.5.1
|
||||
- Add ss parser
|
||||
- Add stat parser
|
||||
|
||||
@@ -5,14 +5,19 @@ cd jc
|
||||
pydocmd simple jc+ > ../docs/readme.md
|
||||
pydocmd simple utils+ > ../docs/utils.md
|
||||
pydocmd simple jc.parsers.arp+ > ../docs/parsers/arp.md
|
||||
pydocmd simple jc.parsers.crontab+ > ../docs/parsers/crontab.md
|
||||
pydocmd simple jc.parsers.crontab_u+ > ../docs/parsers/crontab_u.md
|
||||
pydocmd simple jc.parsers.df+ > ../docs/parsers/df.md
|
||||
pydocmd simple jc.parsers.dig+ > ../docs/parsers/dig.md
|
||||
pydocmd simple jc.parsers.du+ > ../docs/parsers/du.md
|
||||
pydocmd simple jc.parsers.env+ > ../docs/parsers/env.md
|
||||
pydocmd simple jc.parsers.free+ > ../docs/parsers/free.md
|
||||
pydocmd simple jc.parsers.fstab+ > ../docs/parsers/fstab.md
|
||||
pydocmd simple jc.parsers.history+ > ../docs/parsers/history.md
|
||||
pydocmd simple jc.parsers.hosts+ > ../docs/parsers/hosts.md
|
||||
pydocmd simple jc.parsers.id+ > ../docs/parsers/id.md
|
||||
pydocmd simple jc.parsers.ifconfig+ > ../docs/parsers/ifconfig.md
|
||||
pydocmd simple jc.parsers.ini+ > ../docs/parsers/ini.md
|
||||
pydocmd simple jc.parsers.iptables+ > ../docs/parsers/iptables.md
|
||||
pydocmd simple jc.parsers.jobs+ > ../docs/parsers/jobs.md
|
||||
pydocmd simple jc.parsers.ls+ > ../docs/parsers/ls.md
|
||||
@@ -21,6 +26,8 @@ pydocmd simple jc.parsers.lsmod+ > ../docs/parsers/lsmod.md
|
||||
pydocmd simple jc.parsers.lsof+ > ../docs/parsers/lsof.md
|
||||
pydocmd simple jc.parsers.mount+ > ../docs/parsers/mount.md
|
||||
pydocmd simple jc.parsers.netstat+ > ../docs/parsers/netstat.md
|
||||
pydocmd simple jc.parsers.pip_list+ > ../docs/parsers/pip_list.md
|
||||
pydocmd simple jc.parsers.pip_show+ > ../docs/parsers/pip_show.md
|
||||
pydocmd simple jc.parsers.ps+ > ../docs/parsers/ps.md
|
||||
pydocmd simple jc.parsers.route+ > ../docs/parsers/route.md
|
||||
pydocmd simple jc.parsers.ss+ > ../docs/parsers/ss.md
|
||||
@@ -32,3 +39,5 @@ pydocmd simple jc.parsers.systemctl_luf+ > ../docs/parsers/systemctl_luf.md
|
||||
pydocmd simple jc.parsers.uname+ > ../docs/parsers/uname.md
|
||||
pydocmd simple jc.parsers.uptime+ > ../docs/parsers/uptime.md
|
||||
pydocmd simple jc.parsers.w+ > ../docs/parsers/w.md
|
||||
pydocmd simple jc.parsers.xml+ > ../docs/parsers/xml.md
|
||||
pydocmd simple jc.parsers.yaml+ > ../docs/parsers/yaml.md
|
||||
|
||||
@@ -2,7 +2,16 @@
|
||||
jc - JSON CLI output utility arp Parser
|
||||
|
||||
Usage:
|
||||
specify --arp as the first argument if the piped input is coming from arp
|
||||
|
||||
specify --arp as the first argument if the piped input is coming from:
|
||||
|
||||
arp
|
||||
or
|
||||
arp -a
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'aix', 'freebsd', 'darwin'
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -78,6 +87,11 @@ Examples:
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -91,7 +105,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -119,5 +133,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
197
docs/parsers/crontab.md
Normal file
197
docs/parsers/crontab.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# jc.parsers.crontab
|
||||
jc - JSON CLI output utility crontab command and file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --crontab as the first argument if the piped input is coming from crontab -l or a crontab file
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ crontab -l | jc --crontab -p
|
||||
{
|
||||
"variables": [
|
||||
{
|
||||
"name": "MAILTO",
|
||||
"value": "root"
|
||||
},
|
||||
{
|
||||
"name": "PATH",
|
||||
"value": "/sbin:/bin:/usr/sbin:/usr/bin"
|
||||
},
|
||||
{
|
||||
"name": "SHELL",
|
||||
"value": "/bin/bash"
|
||||
}
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
"minute": [
|
||||
"5"
|
||||
],
|
||||
"hour": [
|
||||
"10-11",
|
||||
"22"
|
||||
],
|
||||
"day_of_month": [
|
||||
"*"
|
||||
],
|
||||
"month": [
|
||||
"*"
|
||||
],
|
||||
"day_of_week": [
|
||||
"*"
|
||||
],
|
||||
"command": "/var/www/devdaily.com/bin/mk-new-links.php"
|
||||
},
|
||||
{
|
||||
"minute": [
|
||||
"30"
|
||||
],
|
||||
"hour": [
|
||||
"4/2"
|
||||
],
|
||||
"day_of_month": [
|
||||
"*"
|
||||
],
|
||||
"month": [
|
||||
"*"
|
||||
],
|
||||
"day_of_week": [
|
||||
"*"
|
||||
],
|
||||
"command": "/var/www/devdaily.com/bin/create-all-backups.sh"
|
||||
},
|
||||
{
|
||||
"occurrence": "yearly",
|
||||
"command": "/home/maverick/bin/annual-maintenance"
|
||||
},
|
||||
{
|
||||
"occurrence": "reboot",
|
||||
"command": "/home/cleanup"
|
||||
},
|
||||
{
|
||||
"occurrence": "monthly",
|
||||
"command": "/home/maverick/bin/tape-backup"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
$ cat /etc/crontab | jc --crontab -p -r
|
||||
{
|
||||
"variables": [
|
||||
{
|
||||
"name": "MAILTO",
|
||||
"value": "root"
|
||||
},
|
||||
{
|
||||
"name": "PATH",
|
||||
"value": "/sbin:/bin:/usr/sbin:/usr/bin"
|
||||
},
|
||||
{
|
||||
"name": "SHELL",
|
||||
"value": "/bin/bash"
|
||||
}
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
"minute": "5",
|
||||
"hour": "10-11,22",
|
||||
"day_of_month": "*",
|
||||
"month": "*",
|
||||
"day_of_week": "*",
|
||||
"command": "/var/www/devdaily.com/bin/mk-new-links.php"
|
||||
},
|
||||
{
|
||||
"minute": "30",
|
||||
"hour": "4/2",
|
||||
"day_of_month": "*",
|
||||
"month": "*",
|
||||
"day_of_week": "*",
|
||||
"command": "/var/www/devdaily.com/bin/create-all-backups.sh"
|
||||
},
|
||||
{
|
||||
"occurrence": "yearly",
|
||||
"command": "/home/maverick/bin/annual-maintenance"
|
||||
},
|
||||
{
|
||||
"occurrence": "reboot",
|
||||
"command": "/home/cleanup"
|
||||
},
|
||||
{
|
||||
"occurrence": "monthly",
|
||||
"command": "/home/maverick/bin/tape-backup"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Structured data with the following schema:
|
||||
|
||||
{
|
||||
"variables": [
|
||||
"name": string,
|
||||
"value": string
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
"occurrence" string,
|
||||
"minute": [
|
||||
string
|
||||
],
|
||||
"hour": [
|
||||
string
|
||||
],
|
||||
"day_of_month": [
|
||||
string
|
||||
],
|
||||
"month": [
|
||||
string
|
||||
],
|
||||
"day_of_week": [
|
||||
string
|
||||
],
|
||||
"occurrence": string,
|
||||
"command": string
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
199
docs/parsers/crontab_u.md
Normal file
199
docs/parsers/crontab_u.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# jc.parsers.crontab_u
|
||||
jc - JSON CLI output utility crontab file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --crontab-u as the first argument if the piped input is coming from a crontab file with User specified
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/crontab | jc --crontab-u -p
|
||||
{
|
||||
"variables": [
|
||||
{
|
||||
"name": "PATH",
|
||||
"value": "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
|
||||
},
|
||||
{
|
||||
"name": "SHELL",
|
||||
"value": "/bin/sh"
|
||||
}
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
"minute": [
|
||||
"25"
|
||||
],
|
||||
"hour": [
|
||||
"6"
|
||||
],
|
||||
"day_of_month": [
|
||||
"*"
|
||||
],
|
||||
"month": [
|
||||
"*"
|
||||
],
|
||||
"day_of_week": [
|
||||
"*"
|
||||
],
|
||||
"user": "root",
|
||||
"command": "test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )"
|
||||
},
|
||||
{
|
||||
"minute": [
|
||||
"47"
|
||||
],
|
||||
"hour": [
|
||||
"6"
|
||||
],
|
||||
"day_of_month": [
|
||||
"*"
|
||||
],
|
||||
"month": [
|
||||
"*"
|
||||
],
|
||||
"day_of_week": [
|
||||
"7"
|
||||
],
|
||||
"user": "root",
|
||||
"command": "test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )"
|
||||
},
|
||||
{
|
||||
"minute": [
|
||||
"52"
|
||||
],
|
||||
"hour": [
|
||||
"6"
|
||||
],
|
||||
"day_of_month": [
|
||||
"1"
|
||||
],
|
||||
"month": [
|
||||
"*"
|
||||
],
|
||||
"day_of_week": [
|
||||
"*"
|
||||
],
|
||||
"user": "root",
|
||||
"command": "test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
$ cat /etc/crontab | jc --crontab-u -p -r
|
||||
{
|
||||
"variables": [
|
||||
{
|
||||
"name": "PATH",
|
||||
"value": "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
|
||||
},
|
||||
{
|
||||
"name": "SHELL",
|
||||
"value": "/bin/sh"
|
||||
}
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
"minute": "25",
|
||||
"hour": "6",
|
||||
"day_of_month": "*",
|
||||
"month": "*",
|
||||
"day_of_week": "*",
|
||||
"user": "root",
|
||||
"command": "test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )"
|
||||
},
|
||||
{
|
||||
"minute": "47",
|
||||
"hour": "6",
|
||||
"day_of_month": "*",
|
||||
"month": "*",
|
||||
"day_of_week": "7",
|
||||
"user": "root",
|
||||
"command": "test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )"
|
||||
},
|
||||
{
|
||||
"minute": "52",
|
||||
"hour": "6",
|
||||
"day_of_month": "1",
|
||||
"month": "*",
|
||||
"day_of_week": "*",
|
||||
"user": "root",
|
||||
"command": "test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Structured data with the following schema:
|
||||
|
||||
{
|
||||
"variables": [
|
||||
"name": string,
|
||||
"value": string
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
"occurrence" string,
|
||||
"minute": [
|
||||
string
|
||||
],
|
||||
"hour": [
|
||||
string
|
||||
],
|
||||
"day_of_month": [
|
||||
string
|
||||
],
|
||||
"month": [
|
||||
string
|
||||
],
|
||||
"day_of_week": [
|
||||
string
|
||||
],
|
||||
"occurrence": string,
|
||||
"user": string,
|
||||
"command": string
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
@@ -2,15 +2,20 @@
|
||||
jc - JSON CLI output utility df Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --df as the first argument if the piped input is coming from df
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin'
|
||||
|
||||
Examples:
|
||||
|
||||
$ df | jc --df -p
|
||||
[
|
||||
{
|
||||
"filesystem": "devtmpfs",
|
||||
"1k-blocks": 1918820,
|
||||
"1k_blocks": 1918820,
|
||||
"used": 0,
|
||||
"available": 1918820,
|
||||
"use_percent": 0,
|
||||
@@ -18,7 +23,7 @@ Examples:
|
||||
},
|
||||
{
|
||||
"filesystem": "tmpfs",
|
||||
"1k-blocks": 1930668,
|
||||
"1k_blocks": 1930668,
|
||||
"used": 0,
|
||||
"available": 1930668,
|
||||
"use_percent": 0,
|
||||
@@ -26,7 +31,7 @@ Examples:
|
||||
},
|
||||
{
|
||||
"filesystem": "tmpfs",
|
||||
"1k-blocks": 1930668,
|
||||
"1k_blocks": 1930668,
|
||||
"used": 11800,
|
||||
"available": 1918868,
|
||||
"use_percent": 1,
|
||||
@@ -39,7 +44,7 @@ Examples:
|
||||
[
|
||||
{
|
||||
"filesystem": "devtmpfs",
|
||||
"1k-blocks": "1918820",
|
||||
"1k_blocks": "1918820",
|
||||
"used": "0",
|
||||
"available": "1918820",
|
||||
"use_percent": "0%",
|
||||
@@ -47,7 +52,7 @@ Examples:
|
||||
},
|
||||
{
|
||||
"filesystem": "tmpfs",
|
||||
"1k-blocks": "1930668",
|
||||
"1k_blocks": "1930668",
|
||||
"used": "0",
|
||||
"available": "1930668",
|
||||
"use_percent": "0%",
|
||||
@@ -55,7 +60,7 @@ Examples:
|
||||
},
|
||||
{
|
||||
"filesystem": "tmpfs",
|
||||
"1k-blocks": "1930668",
|
||||
"1k_blocks": "1930668",
|
||||
"used": "11800",
|
||||
"available": "1918868",
|
||||
"use_percent": "1%",
|
||||
@@ -64,6 +69,11 @@ Examples:
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -77,17 +87,22 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"filesystem": string,
|
||||
"size": string,
|
||||
"1k-blocks": integer,
|
||||
"used": integer,
|
||||
"available": integer,
|
||||
"use_percent": integer,
|
||||
"mounted_on": string
|
||||
"filesystem": string,
|
||||
"size": string,
|
||||
"1k_blocks": integer,
|
||||
"512_blocks": integer,
|
||||
"used": integer,
|
||||
"available": integer,
|
||||
"capacity_percent": integer,
|
||||
"ifree": integer,
|
||||
"iused": integer,
|
||||
"use_percent": integer,
|
||||
"iused_percent": integer,
|
||||
"mounted_on": string
|
||||
}
|
||||
]
|
||||
|
||||
@@ -106,5 +121,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility dig Parser
|
||||
|
||||
Usage:
|
||||
|
||||
Specify --dig as the first argument if the piped input is coming from dig
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ dig cnn.com www.cnn.com @205.251.194.64 | jc --dig -p
|
||||
@@ -316,6 +321,11 @@ Examples:
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -329,7 +339,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -388,5 +398,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
115
docs/parsers/du.md
Normal file
115
docs/parsers/du.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# jc.parsers.du
|
||||
jc - JSON CLI output utility du Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --du as the first argument if the piped input is coming from du
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ du /usr | jc --du -p
|
||||
[
|
||||
{
|
||||
"size": 104608,
|
||||
"name": "/usr/bin"
|
||||
},
|
||||
{
|
||||
"size": 56,
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/_CodeSignature"
|
||||
},
|
||||
{
|
||||
"size": 0,
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/usr/local/standalone"
|
||||
},
|
||||
{
|
||||
"size": 0,
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/usr/local"
|
||||
},
|
||||
{
|
||||
"size": 0,
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/usr"
|
||||
},
|
||||
{
|
||||
"size": 1008,
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/dfu"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ du /usr | jc --du -p -r
|
||||
[
|
||||
{
|
||||
"size": "104608",
|
||||
"name": "/usr/bin"
|
||||
},
|
||||
{
|
||||
"size": "56",
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/_CodeSignature"
|
||||
},
|
||||
{
|
||||
"size": "0",
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/usr/local/standalone"
|
||||
},
|
||||
{
|
||||
"size": "0",
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/usr/local"
|
||||
},
|
||||
{
|
||||
"size": "0",
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/usr"
|
||||
},
|
||||
{
|
||||
"size": "1008",
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/dfu"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"size": integer,
|
||||
"name": string
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility env Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --env as the first argument if the piped input is coming from env
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ env | jc --env -p
|
||||
@@ -44,6 +49,11 @@ Examples:
|
||||
"_": "/usr/bin/env"
|
||||
}
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -57,7 +67,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -81,5 +91,6 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
Dictionary of raw structured data or
|
||||
list of dictionaries of processed structured data
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility free Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --free as the first argument if the piped input is coming from free
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ free | jc --free -p
|
||||
@@ -44,6 +49,11 @@ Examples:
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -57,7 +67,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -86,5 +96,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility fstab Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --fstab as the first argument if the piped input is coming from a fstab file
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/fstab | jc --fstab -p
|
||||
@@ -62,6 +67,11 @@ Examples:
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -75,7 +85,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -103,5 +113,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,26 +2,31 @@
|
||||
jc - JSON CLI output utility history Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --history as the first argument if the piped input is coming from history
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ history | jc --history -p
|
||||
[
|
||||
{
|
||||
"line": "118",
|
||||
"line": 118,
|
||||
"command": "sleep 100"
|
||||
},
|
||||
{
|
||||
"line": "119",
|
||||
"line": 119,
|
||||
"command": "ls /bin"
|
||||
},
|
||||
{
|
||||
"line": "120",
|
||||
"line": 120,
|
||||
"command": "echo "hello""
|
||||
},
|
||||
{
|
||||
"line": "121",
|
||||
"line": 121,
|
||||
"command": "docker images"
|
||||
},
|
||||
...
|
||||
@@ -36,6 +41,11 @@ Examples:
|
||||
...
|
||||
}
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -49,11 +59,11 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"line": string,
|
||||
"line": integer,
|
||||
"command": string
|
||||
}
|
||||
]
|
||||
@@ -73,5 +83,6 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
Dictionary of raw structured data or
|
||||
list of dictionaries of processed structured data
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility hosts Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --hosts as the first argument if the piped input is coming from a hosts file
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/hosts | jc --hosts -p
|
||||
@@ -53,6 +58,11 @@ Examples:
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -66,7 +76,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -92,5 +102,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
133
docs/parsers/id.md
Normal file
133
docs/parsers/id.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# jc.parsers.id
|
||||
jc - JSON CLI output utility id Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --id as the first argument if the piped input is coming from id
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ id | jc --id -p
|
||||
{
|
||||
"uid": {
|
||||
"id": 1000,
|
||||
"name": "joeuser"
|
||||
},
|
||||
"gid": {
|
||||
"id": 1000,
|
||||
"name": "joeuser"
|
||||
},
|
||||
"groups": [
|
||||
{
|
||||
"id": 1000,
|
||||
"name": "joeuser"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "wheel"
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"user": "unconfined_u",
|
||||
"role": "unconfined_r",
|
||||
"type": "unconfined_t",
|
||||
"level": "s0-s0:c0.c1023"
|
||||
}
|
||||
}
|
||||
|
||||
$ id | jc --id -p -r
|
||||
{
|
||||
"uid": {
|
||||
"id": "1000",
|
||||
"name": "joeuser"
|
||||
},
|
||||
"gid": {
|
||||
"id": "1000",
|
||||
"name": "joeuser"
|
||||
},
|
||||
"groups": [
|
||||
{
|
||||
"id": "1000",
|
||||
"name": "joeuser"
|
||||
},
|
||||
{
|
||||
"id": "10",
|
||||
"name": "wheel"
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"user": "unconfined_u",
|
||||
"role": "unconfined_r",
|
||||
"type": "unconfined_t",
|
||||
"level": "s0-s0:c0.c1023"
|
||||
}
|
||||
}
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Structured data with the following schema:
|
||||
|
||||
{
|
||||
"uid": {
|
||||
"id": integer,
|
||||
"name": string
|
||||
},
|
||||
"gid": {
|
||||
"id": integer,
|
||||
"name": string
|
||||
},
|
||||
"groups": [
|
||||
{
|
||||
"id": integer,
|
||||
"name": string
|
||||
},
|
||||
{
|
||||
"id": integer,
|
||||
"name": string
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"user": string,
|
||||
"role": string,
|
||||
"type": string,
|
||||
"level": string
|
||||
}
|
||||
}
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
@@ -2,10 +2,15 @@
|
||||
jc - JSON CLI output utility ifconfig Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ifconfig as the first argument if the piped input is coming from ifconfig
|
||||
|
||||
no ifconfig options are supported.
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'aix', 'freebsd', 'darwin'
|
||||
|
||||
Examples:
|
||||
|
||||
$ ifconfig | jc --ifconfig -p
|
||||
@@ -13,22 +18,29 @@ Examples:
|
||||
{
|
||||
"name": "ens33",
|
||||
"flags": 4163,
|
||||
"state": "UP,BROADCAST,RUNNING,MULTICAST",
|
||||
"state": [
|
||||
"UP",
|
||||
"BROADCAST",
|
||||
"RUNNING",
|
||||
"MULTICAST"
|
||||
],
|
||||
"mtu": 1500,
|
||||
"ipv4_addr": "192.168.71.138",
|
||||
"ipv4_addr": "192.168.71.137",
|
||||
"ipv4_mask": "255.255.255.0",
|
||||
"ipv4_bcast": "192.168.71.255",
|
||||
"ipv6_addr": "fe80::c1cb:715d:bc3e:b8a0",
|
||||
"ipv6_mask": 64,
|
||||
"ipv6_scope": "link",
|
||||
"ipv6_scope": "0x20",
|
||||
"mac_addr": "00:0c:29:3b:58:0e",
|
||||
"type": "Ethernet",
|
||||
"rx_packets": 6374,
|
||||
"rx_packets": 8061,
|
||||
"rx_bytes": 1514413,
|
||||
"rx_errors": 0,
|
||||
"rx_dropped": 0,
|
||||
"rx_overruns": 0,
|
||||
"rx_frame": 0,
|
||||
"tx_packets": 3707,
|
||||
"tx_packets": 4502,
|
||||
"tx_bytes": 866622,
|
||||
"tx_errors": 0,
|
||||
"tx_dropped": 0,
|
||||
"tx_overruns": 0,
|
||||
@@ -39,22 +51,28 @@ Examples:
|
||||
{
|
||||
"name": "lo",
|
||||
"flags": 73,
|
||||
"state": "UP,LOOPBACK,RUNNING",
|
||||
"state": [
|
||||
"UP",
|
||||
"LOOPBACK",
|
||||
"RUNNING"
|
||||
],
|
||||
"mtu": 65536,
|
||||
"ipv4_addr": "127.0.0.1",
|
||||
"ipv4_mask": "255.0.0.0",
|
||||
"ipv4_bcast": null,
|
||||
"ipv6_addr": "::1",
|
||||
"ipv6_mask": 128,
|
||||
"ipv6_scope": "host",
|
||||
"ipv6_scope": "0x10",
|
||||
"mac_addr": null,
|
||||
"type": "Local Loopback",
|
||||
"rx_packets": 81,
|
||||
"rx_packets": 73,
|
||||
"rx_bytes": 6009,
|
||||
"rx_errors": 0,
|
||||
"rx_dropped": 0,
|
||||
"rx_overruns": 0,
|
||||
"rx_frame": 0,
|
||||
"tx_packets": 81,
|
||||
"tx_packets": 73,
|
||||
"tx_bytes": 6009,
|
||||
"tx_errors": 0,
|
||||
"tx_dropped": 0,
|
||||
"tx_overruns": 0,
|
||||
@@ -71,20 +89,22 @@ Examples:
|
||||
"flags": "4163",
|
||||
"state": "UP,BROADCAST,RUNNING,MULTICAST",
|
||||
"mtu": "1500",
|
||||
"ipv4_addr": "192.168.71.135",
|
||||
"ipv4_addr": "192.168.71.137",
|
||||
"ipv4_mask": "255.255.255.0",
|
||||
"ipv4_bcast": "192.168.71.255",
|
||||
"ipv6_addr": "fe80::c1cb:715d:bc3e:b8a0",
|
||||
"ipv6_mask": "64",
|
||||
"ipv6_scope": "link",
|
||||
"ipv6_scope": "0x20",
|
||||
"mac_addr": "00:0c:29:3b:58:0e",
|
||||
"type": "Ethernet",
|
||||
"rx_packets": "26348",
|
||||
"rx_packets": "8061",
|
||||
"rx_bytes": "1514413",
|
||||
"rx_errors": "0",
|
||||
"rx_dropped": "0",
|
||||
"rx_overruns": "0",
|
||||
"rx_frame": "0",
|
||||
"tx_packets": "5308",
|
||||
"tx_packets": "4502",
|
||||
"tx_bytes": "866622",
|
||||
"tx_errors": "0",
|
||||
"tx_dropped": "0",
|
||||
"tx_overruns": "0",
|
||||
@@ -102,15 +122,17 @@ Examples:
|
||||
"ipv4_bcast": null,
|
||||
"ipv6_addr": "::1",
|
||||
"ipv6_mask": "128",
|
||||
"ipv6_scope": "host",
|
||||
"ipv6_scope": "0x10",
|
||||
"mac_addr": null,
|
||||
"type": "Local Loopback",
|
||||
"rx_packets": "64",
|
||||
"rx_packets": "73",
|
||||
"rx_bytes": "6009",
|
||||
"rx_errors": "0",
|
||||
"rx_dropped": "0",
|
||||
"rx_overruns": "0",
|
||||
"rx_frame": "0",
|
||||
"tx_packets": "64",
|
||||
"tx_packets": "73",
|
||||
"tx_bytes": "6009",
|
||||
"tx_errors": "0",
|
||||
"tx_dropped": "0",
|
||||
"tx_overruns": "0",
|
||||
@@ -120,6 +142,11 @@ Examples:
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -133,13 +160,15 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"name": string,
|
||||
"flags": integer,
|
||||
"state": string,
|
||||
"state": [
|
||||
string
|
||||
],
|
||||
"mtu": integer,
|
||||
"ipv4_addr": string,
|
||||
"ipv4_mask": string,
|
||||
@@ -150,11 +179,13 @@ Returns:
|
||||
"mac_addr": string,
|
||||
"type": string,
|
||||
"rx_packets": integer,
|
||||
"rx_bytes": integer,
|
||||
"rx_errors": integer,
|
||||
"rx_dropped": integer,
|
||||
"rx_overruns": integer,
|
||||
"rx_frame": integer,
|
||||
"tx_packets": integer,
|
||||
"tx_bytes": integer,
|
||||
"tx_errors": integer,
|
||||
"tx_dropped": integer,
|
||||
"tx_overruns": integer,
|
||||
@@ -179,5 +210,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
87
docs/parsers/ini.md
Normal file
87
docs/parsers/ini.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# jc.parsers.ini
|
||||
jc - JSON CLI output utility INI Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ini as the first argument if the piped input is coming from an INI file
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat example.ini
|
||||
[DEFAULT]
|
||||
ServerAliveInterval = 45
|
||||
Compression = yes
|
||||
CompressionLevel = 9
|
||||
ForwardX11 = yes
|
||||
|
||||
[bitbucket.org]
|
||||
User = hg
|
||||
|
||||
[topsecret.server.com]
|
||||
Port = 50022
|
||||
ForwardX11 = no
|
||||
|
||||
$ cat example.ini | jc --ini -p
|
||||
{
|
||||
"bitbucket.org": {
|
||||
"serveraliveinterval": "45",
|
||||
"compression": "yes",
|
||||
"compressionlevel": "9",
|
||||
"forwardx11": "yes",
|
||||
"user": "hg"
|
||||
},
|
||||
"topsecret.server.com": {
|
||||
"serveraliveinterval": "45",
|
||||
"compression": "yes",
|
||||
"compressionlevel": "9",
|
||||
"forwardx11": "no",
|
||||
"port": "50022"
|
||||
}
|
||||
}
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary representing an ini document:
|
||||
|
||||
{
|
||||
ini document converted to a dictionary
|
||||
see configparser standard library documentation for more details
|
||||
}
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary representing the ini file
|
||||
|
||||
@@ -2,10 +2,15 @@
|
||||
jc - JSON CLI output utility ipables Parser
|
||||
|
||||
Usage:
|
||||
|
||||
Specify --iptables as the first argument if the piped input is coming from iptables
|
||||
|
||||
Supports -vLn and --line-numbers for all tables
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ sudo iptables --line-numbers -v -L -t nat | jc --iptables -p
|
||||
@@ -126,6 +131,11 @@ Examples:
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -139,7 +149,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -177,5 +187,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,10 +2,15 @@
|
||||
jc - JSON CLI output utility jobs Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --jobs as the first argument if the piped input is coming from jobs
|
||||
|
||||
Also supports the -l option
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Example:
|
||||
|
||||
$ jobs -l | jc --jobs -p
|
||||
@@ -68,6 +73,11 @@ Example:
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -81,7 +91,8 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"job_number": integer,
|
||||
@@ -107,5 +118,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,14 +2,20 @@
|
||||
jc - JSON CLI output utility ls Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ls as the first argument if the piped input is coming from ls
|
||||
|
||||
ls options supported:
|
||||
- None
|
||||
- la
|
||||
- h file sizes will be available in text form with -r but larger file sizes
|
||||
with human readable suffixes will be converted to Null in default view
|
||||
since the parser attempts to convert this field to an integer.
|
||||
- laR
|
||||
--time-style=full-iso
|
||||
- h file sizes will be available in text form with -r but larger file sizes
|
||||
with human readable suffixes will be converted to Null in default view
|
||||
since the parser attempts to convert this field to an integer.
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -135,6 +141,11 @@ Examples:
|
||||
"date": "May 3 2019"
|
||||
}
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -148,13 +159,14 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"filename": string,
|
||||
"flags": string,
|
||||
"links": integer,
|
||||
"parent": string,
|
||||
"owner": string,
|
||||
"group": string,
|
||||
"size": integer,
|
||||
@@ -177,5 +189,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility lsblk Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --lsblk as the first argument if the piped input is coming from lsblk
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ lsblk | jc --lsblk -p
|
||||
@@ -207,6 +212,11 @@ Examples:
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -220,7 +230,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -282,5 +292,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility lsmod Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --lsmod as the first argument if the piped input is coming from lsmod
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ lsmod | jc --lsmod -p
|
||||
@@ -98,6 +103,11 @@ Examples:
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -111,7 +121,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -139,5 +149,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility lsof Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --lsof as the first argument if the piped input is coming from lsof
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ sudo lsof | jc --lsof -p
|
||||
@@ -88,6 +93,11 @@ Examples:
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -101,7 +111,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -133,5 +143,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility mount Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --mount as the first argument if the piped input is coming from mount
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin'
|
||||
|
||||
Example:
|
||||
|
||||
$ mount | jc --mount -p
|
||||
@@ -48,6 +53,11 @@ Example:
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -61,7 +71,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -89,5 +99,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility netstat Parser
|
||||
|
||||
Usage:
|
||||
|
||||
Specify --netstat as the first argument if the piped input is coming from netstat
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ sudo netstat -apee | jc --netstat -p
|
||||
@@ -304,6 +309,11 @@ Examples:
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -317,7 +327,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -361,5 +371,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
75
docs/parsers/pip_list.md
Normal file
75
docs/parsers/pip_list.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# jc.parsers.pip_list
|
||||
jc - JSON CLI output utility pip-list Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --pip-list as the first argument if the piped input is coming from pip list
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ pip list | jc --pip-list -p
|
||||
[
|
||||
{
|
||||
"package": "ansible",
|
||||
"version": "2.8.5"
|
||||
},
|
||||
{
|
||||
"package": "antlr4-python3-runtime",
|
||||
"version": "4.7.2"
|
||||
},
|
||||
{
|
||||
"package": "asn1crypto",
|
||||
"version": "0.24.0"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"package": string,
|
||||
"version": string,
|
||||
"location": string
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
94
docs/parsers/pip_show.md
Normal file
94
docs/parsers/pip_show.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# jc.parsers.pip_show
|
||||
jc - JSON CLI output utility pip-show Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --pip-show as the first argument if the piped input is coming from pip show
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ pip show wrapt jc wheel | jc --pip-show -p
|
||||
[
|
||||
{
|
||||
"name": "wrapt",
|
||||
"version": "1.11.2",
|
||||
"summary": "Module for decorators, wrappers and monkey patching.",
|
||||
"home_page": "https://github.com/GrahamDumpleton/wrapt",
|
||||
"author": "Graham Dumpleton",
|
||||
"author_email": "Graham.Dumpleton@gmail.com",
|
||||
"license": "BSD",
|
||||
"location": "/usr/local/lib/python3.7/site-packages",
|
||||
"requires": null,
|
||||
"required_by": "astroid"
|
||||
},
|
||||
{
|
||||
"name": "wheel",
|
||||
"version": "0.33.4",
|
||||
"summary": "A built-package format for Python.",
|
||||
"home_page": "https://github.com/pypa/wheel",
|
||||
"author": "Daniel Holth",
|
||||
"author_email": "dholth@fastmail.fm",
|
||||
"license": "MIT",
|
||||
"location": "/usr/local/lib/python3.7/site-packages",
|
||||
"requires": null,
|
||||
"required_by": null
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"name": string,
|
||||
"version": string,
|
||||
"summary": string,
|
||||
"home_page": string,
|
||||
"author": string,
|
||||
"author_email": string,
|
||||
"license": string,
|
||||
"location": string,
|
||||
"requires": string,
|
||||
"required_by": string
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
@@ -2,12 +2,17 @@
|
||||
jc - JSON CLI output utility ps Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ps as the first argument if the piped input is coming from ps
|
||||
|
||||
ps options supported:
|
||||
- ef
|
||||
- axu
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ ps -ef | jc --ps -p
|
||||
@@ -168,6 +173,11 @@ Examples:
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -181,7 +191,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -190,7 +200,8 @@ Returns:
|
||||
"ppid": integer,
|
||||
"c": integer,
|
||||
"stime": string,
|
||||
"tty": string, # ? = Null
|
||||
"tty": string, # ? or ?? = Null
|
||||
"tt": string, # ?? = Null
|
||||
"time": string,
|
||||
"cmd": string,
|
||||
"user": string,
|
||||
@@ -219,5 +230,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility route Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --route as the first argument if the piped input is coming from route
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ route -ee | jc --route -p
|
||||
@@ -92,6 +97,11 @@ Examples:
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -105,7 +115,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -138,5 +148,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,11 +2,17 @@
|
||||
jc - JSON CLI output utility ss Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ss as the first argument if the piped input is coming from ss
|
||||
|
||||
Limitations:
|
||||
|
||||
Extended information options like -e and -p are not supported and may cause parsing irregularities
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ sudo ss -a | jc --ss -p
|
||||
@@ -241,6 +247,11 @@ Examples:
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -254,7 +265,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -293,5 +304,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
# jc.parsers.stat
|
||||
jc - JSON CLI output utility stats Parser
|
||||
jc - JSON CLI output utility stat Parser
|
||||
|
||||
Usage:
|
||||
specify --stats as the first argument if the piped input is coming from stats
|
||||
|
||||
specify --stat as the first argument if the piped input is coming from stat
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -96,6 +101,11 @@ Examples:
|
||||
..
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -109,7 +119,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -150,5 +160,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility systemctl Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --systemctl as the first argument if the piped input is coming from systemctl
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ systemctl -a | jc --systemctl -p
|
||||
@@ -32,6 +37,11 @@ Examples:
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -45,7 +55,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -72,5 +82,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility systemctl-lj Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --systemctl-lj as the first argument if the piped input is coming from systemctl list-jobs
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ systemctl list-jobs| jc --systemctl-lj -p
|
||||
@@ -51,6 +56,11 @@ Examples:
|
||||
]
|
||||
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -64,7 +74,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -90,5 +100,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility systemctl-ls Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --systemctl-ls as the first argument if the piped input is coming from systemctl list-sockets
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ systemctl list-sockets | jc --systemctl-ls -p
|
||||
@@ -26,6 +31,11 @@ Examples:
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -39,7 +49,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -64,5 +74,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility systemctl-luf Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --systemctl-luf as the first argument if the piped input is coming from systemctl list-unit-files
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ systemctl list-unit-files | jc --systemctl-luf -p
|
||||
@@ -23,6 +28,11 @@ Examples:
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -36,7 +46,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -60,5 +70,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,11 +2,17 @@
|
||||
jc - JSON CLI output utility uname Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --uname as the first argument if the piped input is coming from uname
|
||||
|
||||
Limitations:
|
||||
|
||||
must use 'uname -a'
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin'
|
||||
|
||||
Example:
|
||||
|
||||
$ uname -a | jc --uname -p
|
||||
@@ -21,6 +27,11 @@ Example:
|
||||
"kernel_version": "#74-Ubuntu SMP Tue Sep 17 17:06:04 UTC 2019"
|
||||
}
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -34,7 +45,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
Dictionary. Structured data with the following schema:
|
||||
|
||||
{
|
||||
"kernel_name": string,
|
||||
@@ -62,5 +73,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility uptime Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --uptime as the first argument if the piped input is coming from uptime
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Example:
|
||||
|
||||
$ uptime | jc --uptime -p
|
||||
@@ -26,6 +31,11 @@ Example:
|
||||
"load_15m": "0.05"
|
||||
}
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -39,7 +49,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
Dictionary. Structured data with the following schema:
|
||||
|
||||
{
|
||||
"time": string,
|
||||
@@ -65,5 +75,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
Dictionary. Raw or processed structured data
|
||||
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
jc - JSON CLI output utility w Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --w as the first argument if the piped input is coming from w
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ w | jc --w -p
|
||||
@@ -74,6 +79,11 @@ Examples:
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
@@ -87,7 +97,7 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -117,5 +127,5 @@ Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
|
||||
99
docs/parsers/xml.md
Normal file
99
docs/parsers/xml.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# jc.parsers.xml
|
||||
jc - JSON CLI output utility XML Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --xml as the first argument if the piped input is coming from an XML file
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat cd_catalog.xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CATALOG>
|
||||
<CD>
|
||||
<TITLE>Empire Burlesque</TITLE>
|
||||
<ARTIST>Bob Dylan</ARTIST>
|
||||
<COUNTRY>USA</COUNTRY>
|
||||
<COMPANY>Columbia</COMPANY>
|
||||
<PRICE>10.90</PRICE>
|
||||
<YEAR>1985</YEAR>
|
||||
</CD>
|
||||
<CD>
|
||||
<TITLE>Hide your heart</TITLE>
|
||||
<ARTIST>Bonnie Tyler</ARTIST>
|
||||
<COUNTRY>UK</COUNTRY>
|
||||
<COMPANY>CBS Records</COMPANY>
|
||||
<PRICE>9.90</PRICE>
|
||||
<YEAR>1988</YEAR>
|
||||
</CD>
|
||||
...
|
||||
|
||||
$ cat cd_catalog.xml | jc --xml -p
|
||||
{
|
||||
"CATALOG": {
|
||||
"CD": [
|
||||
{
|
||||
"TITLE": "Empire Burlesque",
|
||||
"ARTIST": "Bob Dylan",
|
||||
"COUNTRY": "USA",
|
||||
"COMPANY": "Columbia",
|
||||
"PRICE": "10.90",
|
||||
"YEAR": "1985"
|
||||
},
|
||||
{
|
||||
"TITLE": "Hide your heart",
|
||||
"ARTIST": "Bonnie Tyler",
|
||||
"COUNTRY": "UK",
|
||||
"COMPANY": "CBS Records",
|
||||
"PRICE": "9.90",
|
||||
"YEAR": "1988"
|
||||
},
|
||||
...
|
||||
}
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary representing an XML document:
|
||||
|
||||
{
|
||||
XML Document converted to a Dictionary
|
||||
See https://github.com/martinblech/xmltodict for details
|
||||
}
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
113
docs/parsers/yaml.md
Normal file
113
docs/parsers/yaml.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# jc.parsers.yaml
|
||||
jc - JSON CLI output utility YAML Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --yaml as the first argument if the piped input is coming from a YAML file
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat istio-mtls-permissive.yaml
|
||||
apiVersion: "authentication.istio.io/v1alpha1"
|
||||
kind: "Policy"
|
||||
metadata:
|
||||
name: "default"
|
||||
namespace: "default"
|
||||
spec:
|
||||
peers:
|
||||
- mtls: {}
|
||||
---
|
||||
apiVersion: "networking.istio.io/v1alpha3"
|
||||
kind: "DestinationRule"
|
||||
metadata:
|
||||
name: "default"
|
||||
namespace: "default"
|
||||
spec:
|
||||
host: "*.default.svc.cluster.local"
|
||||
trafficPolicy:
|
||||
tls:
|
||||
mode: ISTIO_MUTUAL
|
||||
|
||||
$ cat istio-mtls-permissive.yaml | jc --yaml -p
|
||||
[
|
||||
{
|
||||
"apiVersion": "authentication.istio.io/v1alpha1",
|
||||
"kind": "Policy",
|
||||
"metadata": {
|
||||
"name": "default",
|
||||
"namespace": "default"
|
||||
},
|
||||
"spec": {
|
||||
"peers": [
|
||||
{
|
||||
"mtls": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "networking.istio.io/v1alpha3",
|
||||
"kind": "DestinationRule",
|
||||
"metadata": {
|
||||
"name": "default",
|
||||
"namespace": "default"
|
||||
},
|
||||
"spec": {
|
||||
"host": "*.default.svc.cluster.local",
|
||||
"trafficPolicy": {
|
||||
"tls": {
|
||||
"mode": "ISTIO_MUTUAL"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Each dictionary represents a YAML document:
|
||||
|
||||
[
|
||||
{
|
||||
YAML Document converted to a Dictionary
|
||||
See https://pypi.org/project/ruamel.yaml for details
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
371
jc/cli.py
371
jc/cli.py
@@ -1,182 +1,321 @@
|
||||
#!/usr/bin/env python3
|
||||
"""jc - JSON CLI output utility
|
||||
|
||||
JC cli module
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
import shlex
|
||||
import importlib
|
||||
import textwrap
|
||||
import signal
|
||||
import json
|
||||
import jc.utils
|
||||
import jc.parsers.arp
|
||||
import jc.parsers.df
|
||||
import jc.parsers.dig
|
||||
import jc.parsers.env
|
||||
import jc.parsers.free
|
||||
import jc.parsers.fstab
|
||||
import jc.parsers.history
|
||||
import jc.parsers.hosts
|
||||
import jc.parsers.ifconfig
|
||||
import jc.parsers.iptables
|
||||
import jc.parsers.jobs
|
||||
import jc.parsers.ls
|
||||
import jc.parsers.lsblk
|
||||
import jc.parsers.lsmod
|
||||
import jc.parsers.lsof
|
||||
import jc.parsers.mount
|
||||
import jc.parsers.netstat
|
||||
import jc.parsers.ps
|
||||
import jc.parsers.route
|
||||
import jc.parsers.ss
|
||||
import jc.parsers.stat
|
||||
import jc.parsers.systemctl
|
||||
import jc.parsers.systemctl_lj
|
||||
import jc.parsers.systemctl_ls
|
||||
import jc.parsers.systemctl_luf
|
||||
import jc.parsers.uname
|
||||
import jc.parsers.uptime
|
||||
import jc.parsers.w
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.7.4'
|
||||
description = 'jc cli output JSON conversion tool'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
parsers = [
|
||||
'arp',
|
||||
'crontab',
|
||||
'crontab-u',
|
||||
'df',
|
||||
'dig',
|
||||
'du',
|
||||
'env',
|
||||
'free',
|
||||
'fstab',
|
||||
'history',
|
||||
'hosts',
|
||||
'id',
|
||||
'ifconfig',
|
||||
'ini',
|
||||
'iptables',
|
||||
'jobs',
|
||||
'ls',
|
||||
'lsblk',
|
||||
'lsmod',
|
||||
'lsof',
|
||||
'mount',
|
||||
'netstat',
|
||||
'pip-list',
|
||||
'pip-show',
|
||||
'ps',
|
||||
'route',
|
||||
'ss',
|
||||
'stat',
|
||||
'systemctl',
|
||||
'systemctl-lj',
|
||||
'systemctl-ls',
|
||||
'systemctl-luf',
|
||||
'uname',
|
||||
'uptime',
|
||||
'w',
|
||||
'xml',
|
||||
'yaml'
|
||||
]
|
||||
|
||||
|
||||
def ctrlc(signum, frame):
|
||||
exit()
|
||||
"""exit with error on SIGINT"""
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def parser_shortname(parser_argument):
|
||||
"""short name of the parser with dashes and no -- prefix"""
|
||||
return parser_argument[2:]
|
||||
|
||||
|
||||
def parser_argument(parser):
|
||||
"""short name of the parser with dashes and with -- prefix"""
|
||||
return f'--{parser}'
|
||||
|
||||
|
||||
def parser_mod_shortname(parser):
|
||||
"""short name of the parser's module name (no -- prefix and dashes converted to underscores)"""
|
||||
return parser.replace('--', '').replace('-', '_')
|
||||
|
||||
|
||||
def parser_module(parser):
|
||||
"""import the module just in time and return the module object"""
|
||||
importlib.import_module('jc.parsers.' + parser_mod_shortname(parser))
|
||||
return getattr(jc.parsers, parser_mod_shortname(parser))
|
||||
|
||||
|
||||
def parsers_text(indent=0, pad=0):
|
||||
"""return the argument and description information from each parser"""
|
||||
ptext = ''
|
||||
for parser in parsers:
|
||||
parser_arg = parser_argument(parser)
|
||||
parser_mod = parser_module(parser)
|
||||
|
||||
if hasattr(parser_mod, 'info'):
|
||||
parser_desc = parser_mod.info.description
|
||||
padding = pad - len(parser_arg)
|
||||
padding_char = ' '
|
||||
indent_text = padding_char * indent
|
||||
padding_text = padding_char * padding
|
||||
ptext += indent_text + parser_arg + padding_text + parser_desc + '\n'
|
||||
|
||||
return ptext
|
||||
|
||||
|
||||
def about_jc():
|
||||
"""return jc info and the contents of each parser.info as a dictionary"""
|
||||
parser_list = []
|
||||
|
||||
for parser in parsers:
|
||||
parser_mod = parser_module(parser)
|
||||
|
||||
if hasattr(parser_mod, 'info'):
|
||||
info_dict = {}
|
||||
info_dict['name'] = parser_mod.__name__.split('.')[-1]
|
||||
info_dict['argument'] = parser_argument(parser)
|
||||
parser_entry = vars(parser_mod.info)
|
||||
|
||||
for k, v in parser_entry.items():
|
||||
if not k.startswith('__'):
|
||||
info_dict[k] = v
|
||||
|
||||
parser_list.append(info_dict)
|
||||
|
||||
return {
|
||||
'name': 'jc',
|
||||
'version': info.version,
|
||||
'description': info.description,
|
||||
'author': info.author,
|
||||
'author_email': info.author_email,
|
||||
'parser_count': len(parser_list),
|
||||
'parsers': parser_list
|
||||
}
|
||||
|
||||
|
||||
def helptext(message):
|
||||
"""return the help text with the list of parsers"""
|
||||
parsers_string = parsers_text(indent=12, pad=17)
|
||||
|
||||
helptext_string = f'''
|
||||
jc: {message}
|
||||
|
||||
Usage: jc PARSER [OPTIONS]
|
||||
Usage: COMMAND | jc PARSER [OPTIONS]
|
||||
|
||||
or
|
||||
|
||||
COMMAND | jc [OPTIONS] PARSER
|
||||
|
||||
or magic syntax:
|
||||
|
||||
jc [OPTIONS] COMMAND
|
||||
|
||||
Parsers:
|
||||
--arp arp parser
|
||||
--df df parser
|
||||
--dig dig parser
|
||||
--env env parser
|
||||
--free free parser
|
||||
--fstab /etc/fstab file parser
|
||||
--history history parser
|
||||
--hosts /etc/hosts file parser
|
||||
--ifconfig iconfig parser
|
||||
--iptables iptables parser
|
||||
--jobs jobs parser
|
||||
--ls ls parser
|
||||
--lsblk lsblk parser
|
||||
--lsmod lsmod parser
|
||||
--lsof lsof parser
|
||||
--mount mount parser
|
||||
--netstat netstat parser
|
||||
--ps ps parser
|
||||
--route route parser
|
||||
--ss ss parser
|
||||
--stat stat parser
|
||||
--systemctl systemctl parser
|
||||
--systemctl-lj systemctl list-jobs parser
|
||||
--systemctl-ls systemctl list-sockets parser
|
||||
--systemctl-luf systemctl list-unit-files parser
|
||||
--uname uname -a parser
|
||||
--uptime uptime parser
|
||||
--w w parser
|
||||
|
||||
{parsers_string}
|
||||
Options:
|
||||
-d debug - show trace messages
|
||||
-p pretty print output
|
||||
-q quiet - suppress warnings
|
||||
-r raw JSON output
|
||||
-a about jc
|
||||
-d debug - show trace messages
|
||||
-p pretty print output
|
||||
-q quiet - suppress warnings
|
||||
-r raw JSON output
|
||||
|
||||
Example:
|
||||
ls -al | jc --ls -p
|
||||
|
||||
or using the magic syntax:
|
||||
|
||||
jc -p ls -al
|
||||
'''
|
||||
print(textwrap.dedent(helptext_string), file=sys.stderr)
|
||||
|
||||
|
||||
def json_out(data, pretty=False):
|
||||
if pretty:
|
||||
print(json.dumps(data, indent=2))
|
||||
else:
|
||||
print(json.dumps(data))
|
||||
|
||||
|
||||
def magic():
|
||||
"""Parse with magic syntax: jc -p ls -al"""
|
||||
if len(sys.argv) > 1 and not sys.argv[1].startswith('--'):
|
||||
parser_info = about_jc()['parsers']
|
||||
# correctly parse escape characters and spaces with shlex
|
||||
args_given = " ".join(map(shlex.quote, sys.argv[1:])).split()
|
||||
options = []
|
||||
found_parser = None
|
||||
|
||||
# find the options
|
||||
if args_given[0].startswith('-'):
|
||||
p = 0
|
||||
for i, arg in list(enumerate(args_given)):
|
||||
# parser found - use standard syntax
|
||||
if arg.startswith('--'):
|
||||
return
|
||||
# option found - populate option list
|
||||
elif arg.startswith('-'):
|
||||
options.append(args_given.pop(i - p)[1:])
|
||||
p = p + 1
|
||||
# command found if iterator didn't already stop - stop iterating
|
||||
else:
|
||||
break
|
||||
|
||||
# find the command and parser
|
||||
for parser in parser_info:
|
||||
if 'magic_commands' in parser:
|
||||
# first pass for two word commands: e.g. 'pip list'
|
||||
for magic_command in parser['magic_commands']:
|
||||
try:
|
||||
if ' '.join(args_given[0:2]) == magic_command:
|
||||
found_parser = parser['argument']
|
||||
break
|
||||
# No command found - go to next loop (for cases like 'jc -a')
|
||||
except Exception:
|
||||
break
|
||||
|
||||
# second pass for one word commands: e.g. 'ls'
|
||||
if not found_parser:
|
||||
for magic_command in parser['magic_commands']:
|
||||
try:
|
||||
if args_given[0] == magic_command:
|
||||
found_parser = parser['argument']
|
||||
break
|
||||
# No command found - use standard syntax (for cases like 'jc -a')
|
||||
except Exception:
|
||||
return
|
||||
|
||||
# construct a new command line using the standard syntax: COMMAND | jc --PARSER -OPTIONS
|
||||
run_command = ' '.join(args_given)
|
||||
if found_parser:
|
||||
if options:
|
||||
cmd_options = '-' + ''.join(options)
|
||||
else:
|
||||
cmd_options = ''
|
||||
whole_command = ' '.join([run_command, '|', 'jc', found_parser, cmd_options])
|
||||
|
||||
os.system(whole_command)
|
||||
exit()
|
||||
else:
|
||||
helptext(f'parser not found for "{run_command}"')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
# break on ctrl-c keyboard interrupt
|
||||
signal.signal(signal.SIGINT, ctrlc)
|
||||
|
||||
if sys.stdin.isatty():
|
||||
helptext('missing piped data')
|
||||
exit()
|
||||
# try magic syntax first: e.g. jc -p ls -al
|
||||
magic()
|
||||
|
||||
data = sys.stdin.read()
|
||||
options = []
|
||||
debug = False
|
||||
pretty = False
|
||||
quiet = False
|
||||
raw = False
|
||||
|
||||
# options
|
||||
if '-d' in sys.argv:
|
||||
for opt in sys.argv:
|
||||
if opt.startswith('-') and not opt.startswith('--'):
|
||||
for flag in opt[1:]:
|
||||
options.append(flag)
|
||||
|
||||
if 'd' in options:
|
||||
debug = True
|
||||
|
||||
if '-p' in sys.argv:
|
||||
if 'p' in options:
|
||||
pretty = True
|
||||
|
||||
if '-q' in sys.argv:
|
||||
if 'q' in options:
|
||||
quiet = True
|
||||
|
||||
if '-r' in sys.argv:
|
||||
if 'r' in options:
|
||||
raw = True
|
||||
|
||||
# parsers
|
||||
parser_map = {
|
||||
'--arp': jc.parsers.arp.parse,
|
||||
'--df': jc.parsers.df.parse,
|
||||
'--dig': jc.parsers.dig.parse,
|
||||
'--env': jc.parsers.env.parse,
|
||||
'--free': jc.parsers.free.parse,
|
||||
'--fstab': jc.parsers.fstab.parse,
|
||||
'--history': jc.parsers.history.parse,
|
||||
'--hosts': jc.parsers.hosts.parse,
|
||||
'--ifconfig': jc.parsers.ifconfig.parse,
|
||||
'--iptables': jc.parsers.iptables.parse,
|
||||
'--jobs': jc.parsers.jobs.parse,
|
||||
'--ls': jc.parsers.ls.parse,
|
||||
'--lsblk': jc.parsers.lsblk.parse,
|
||||
'--lsmod': jc.parsers.lsmod.parse,
|
||||
'--lsof': jc.parsers.lsof.parse,
|
||||
'--mount': jc.parsers.mount.parse,
|
||||
'--netstat': jc.parsers.netstat.parse,
|
||||
'--ps': jc.parsers.ps.parse,
|
||||
'--route': jc.parsers.route.parse,
|
||||
'--ss': jc.parsers.ss.parse,
|
||||
'--stat': jc.parsers.stat.parse,
|
||||
'--systemctl': jc.parsers.systemctl.parse,
|
||||
'--systemctl-lj': jc.parsers.systemctl_lj.parse,
|
||||
'--systemctl-ls': jc.parsers.systemctl_ls.parse,
|
||||
'--systemctl-luf': jc.parsers.systemctl_luf.parse,
|
||||
'--uname': jc.parsers.uname.parse,
|
||||
'--uptime': jc.parsers.uptime.parse,
|
||||
'--w': jc.parsers.w.parse
|
||||
}
|
||||
if 'a' in options:
|
||||
json_out(about_jc(), pretty=pretty)
|
||||
exit()
|
||||
|
||||
if sys.stdin.isatty():
|
||||
helptext('missing piped data')
|
||||
sys.exit(1)
|
||||
|
||||
data = sys.stdin.read()
|
||||
|
||||
found = False
|
||||
|
||||
if debug:
|
||||
for arg in sys.argv:
|
||||
if arg in parser_map:
|
||||
result = parser_map[arg](data, raw=raw, quiet=quiet)
|
||||
parser_name = parser_shortname(arg)
|
||||
|
||||
if parser_name in parsers:
|
||||
# load parser module just in time so we don't need to load all modules
|
||||
parser = parser_module(arg)
|
||||
result = parser.parse(data, raw=raw, quiet=quiet)
|
||||
found = True
|
||||
break
|
||||
else:
|
||||
for arg in sys.argv:
|
||||
if arg in parser_map:
|
||||
parser_name = parser_shortname(arg)
|
||||
|
||||
if parser_name in parsers:
|
||||
# load parser module just in time so we don't need to load all modules
|
||||
parser = parser_module(arg)
|
||||
try:
|
||||
result = parser_map[arg](data, raw=raw, quiet=quiet)
|
||||
result = parser.parse(data, raw=raw, quiet=quiet)
|
||||
found = True
|
||||
break
|
||||
except:
|
||||
parser_name = arg.lstrip('--')
|
||||
except Exception:
|
||||
jc.utils.error_message(f'{parser_name} parser could not parse the input data. Did you use the correct parser?\n For details use the -d option.')
|
||||
exit(1)
|
||||
sys.exit(1)
|
||||
|
||||
if not found:
|
||||
helptext('missing or incorrect arguments')
|
||||
exit()
|
||||
sys.exit(1)
|
||||
|
||||
# output resulting dictionary as json
|
||||
if pretty:
|
||||
print(json.dumps(result, indent=2))
|
||||
else:
|
||||
print(json.dumps(result))
|
||||
json_out(result, pretty=pretty)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
"""jc - JSON CLI output utility arp Parser
|
||||
|
||||
Usage:
|
||||
specify --arp as the first argument if the piped input is coming from arp
|
||||
|
||||
specify --arp as the first argument if the piped input is coming from:
|
||||
|
||||
arp
|
||||
or
|
||||
arp -a
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'aix', 'freebsd', 'darwin'
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -78,6 +87,21 @@ Examples:
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
import jc.parsers.universal
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'arp command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'aix', 'freebsd', 'darwin']
|
||||
magic_commands = ['arp']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
@@ -90,7 +114,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -124,39 +148,50 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'aix', 'freebsd']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
|
||||
# code adapted from Conor Heine at:
|
||||
# https://gist.github.com/cahna/43a1a3ff4d075bcd71f9d7120037a501
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# remove final Entries row if -v was used
|
||||
if cleandata[-1].find("Entries:") == 0:
|
||||
if cleandata[-1].find('Entries:') == 0:
|
||||
cleandata.pop(-1)
|
||||
|
||||
# detect if linux or bsd style was used
|
||||
if cleandata[0].find('Address') == 0:
|
||||
|
||||
# fix header row to change Flags Mask to flags_mask
|
||||
cleandata[0] = cleandata[0].replace('Flags Mask', 'flags_mask')
|
||||
|
||||
headers = [h for h in ' '.join(cleandata[0].lower().strip().split()).split() if h]
|
||||
raw_data = map(lambda s: s.strip().split(None, len(headers) - 1), cleandata[1:])
|
||||
raw_output = [dict(zip(headers, r)) for r in raw_data]
|
||||
# detect if osx style was used
|
||||
if cleandata[0].find(' ifscope ') != -1:
|
||||
raw_output = []
|
||||
for line in cleandata:
|
||||
line = line.split()
|
||||
output_line = {}
|
||||
output_line['name'] = line[0]
|
||||
output_line['address'] = line[1].lstrip('(').rstrip(')')
|
||||
output_line['hwtype'] = line[-1].lstrip('[').rstrip(']')
|
||||
output_line['hwaddress'] = line[3]
|
||||
output_line['iface'] = line[5]
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
|
||||
# detect if linux style was used
|
||||
elif cleandata[0].find('Address') == 0:
|
||||
|
||||
# fix header row to change Flags Mask to flags_mask
|
||||
cleandata[0] = cleandata[0].replace('Flags Mask', 'flags_mask')
|
||||
cleandata[0] = cleandata[0].lower()
|
||||
|
||||
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
|
||||
# otherwise, try bsd style
|
||||
else:
|
||||
raw_output = []
|
||||
for line in cleandata:
|
||||
|
||||
270
jc/parsers/crontab.py
Normal file
270
jc/parsers/crontab.py
Normal file
@@ -0,0 +1,270 @@
|
||||
"""jc - JSON CLI output utility crontab command and file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --crontab as the first argument if the piped input is coming from crontab -l or a crontab file
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ crontab -l | jc --crontab -p
|
||||
{
|
||||
"variables": [
|
||||
{
|
||||
"name": "MAILTO",
|
||||
"value": "root"
|
||||
},
|
||||
{
|
||||
"name": "PATH",
|
||||
"value": "/sbin:/bin:/usr/sbin:/usr/bin"
|
||||
},
|
||||
{
|
||||
"name": "SHELL",
|
||||
"value": "/bin/bash"
|
||||
}
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
"minute": [
|
||||
"5"
|
||||
],
|
||||
"hour": [
|
||||
"10-11",
|
||||
"22"
|
||||
],
|
||||
"day_of_month": [
|
||||
"*"
|
||||
],
|
||||
"month": [
|
||||
"*"
|
||||
],
|
||||
"day_of_week": [
|
||||
"*"
|
||||
],
|
||||
"command": "/var/www/devdaily.com/bin/mk-new-links.php"
|
||||
},
|
||||
{
|
||||
"minute": [
|
||||
"30"
|
||||
],
|
||||
"hour": [
|
||||
"4/2"
|
||||
],
|
||||
"day_of_month": [
|
||||
"*"
|
||||
],
|
||||
"month": [
|
||||
"*"
|
||||
],
|
||||
"day_of_week": [
|
||||
"*"
|
||||
],
|
||||
"command": "/var/www/devdaily.com/bin/create-all-backups.sh"
|
||||
},
|
||||
{
|
||||
"occurrence": "yearly",
|
||||
"command": "/home/maverick/bin/annual-maintenance"
|
||||
},
|
||||
{
|
||||
"occurrence": "reboot",
|
||||
"command": "/home/cleanup"
|
||||
},
|
||||
{
|
||||
"occurrence": "monthly",
|
||||
"command": "/home/maverick/bin/tape-backup"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
$ cat /etc/crontab | jc --crontab -p -r
|
||||
{
|
||||
"variables": [
|
||||
{
|
||||
"name": "MAILTO",
|
||||
"value": "root"
|
||||
},
|
||||
{
|
||||
"name": "PATH",
|
||||
"value": "/sbin:/bin:/usr/sbin:/usr/bin"
|
||||
},
|
||||
{
|
||||
"name": "SHELL",
|
||||
"value": "/bin/bash"
|
||||
}
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
"minute": "5",
|
||||
"hour": "10-11,22",
|
||||
"day_of_month": "*",
|
||||
"month": "*",
|
||||
"day_of_week": "*",
|
||||
"command": "/var/www/devdaily.com/bin/mk-new-links.php"
|
||||
},
|
||||
{
|
||||
"minute": "30",
|
||||
"hour": "4/2",
|
||||
"day_of_month": "*",
|
||||
"month": "*",
|
||||
"day_of_week": "*",
|
||||
"command": "/var/www/devdaily.com/bin/create-all-backups.sh"
|
||||
},
|
||||
{
|
||||
"occurrence": "yearly",
|
||||
"command": "/home/maverick/bin/annual-maintenance"
|
||||
},
|
||||
{
|
||||
"occurrence": "reboot",
|
||||
"command": "/home/cleanup"
|
||||
},
|
||||
{
|
||||
"occurrence": "monthly",
|
||||
"command": "/home/maverick/bin/tape-backup"
|
||||
}
|
||||
]
|
||||
}
|
||||
"""
|
||||
import jc.utils
|
||||
import jc.parsers.universal
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'crontab command and file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'aix', 'freebsd']
|
||||
magic_commands = ['crontab']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Structured data with the following schema:
|
||||
|
||||
{
|
||||
"variables": [
|
||||
"name": string,
|
||||
"value": string
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
"occurrence" string,
|
||||
"minute": [
|
||||
string
|
||||
],
|
||||
"hour": [
|
||||
string
|
||||
],
|
||||
"day_of_month": [
|
||||
string
|
||||
],
|
||||
"month": [
|
||||
string
|
||||
],
|
||||
"day_of_week": [
|
||||
string
|
||||
],
|
||||
"occurrence": string,
|
||||
"command": string
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
"""
|
||||
# put itmes in lists
|
||||
try:
|
||||
for entry in proc_data['schedule']:
|
||||
entry['minute'] = entry['minute'].split(',')
|
||||
entry['hour'] = entry['hour'].split(',')
|
||||
entry['day_of_month'] = entry['day_of_month'].split(',')
|
||||
entry['month'] = entry['month'].split(',')
|
||||
entry['day_of_week'] = entry['day_of_week'].split(',')
|
||||
except (KeyError):
|
||||
pass
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = {}
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
# Clear any commented lines
|
||||
for i, line in reversed(list(enumerate(cleandata))):
|
||||
if line.strip().find('#') == 0:
|
||||
cleandata.pop(i)
|
||||
|
||||
# Pop any variable assignment lines
|
||||
cron_var = []
|
||||
for i, line in reversed(list(enumerate(cleandata))):
|
||||
if line.find('=') != -1:
|
||||
var_line = cleandata.pop(i)
|
||||
var_name = var_line.split('=', maxsplit=1)[0].strip()
|
||||
var_value = var_line.split('=', maxsplit=1)[1].strip()
|
||||
cron_var.append({'name': var_name,
|
||||
'value': var_value})
|
||||
|
||||
raw_output['variables'] = cron_var
|
||||
|
||||
# Pop any shortcut lines
|
||||
shortcut_list = []
|
||||
for i, line in reversed(list(enumerate(cleandata))):
|
||||
if line.strip().startswith('@'):
|
||||
shortcut_line = cleandata.pop(i)
|
||||
occurrence = shortcut_line.split(maxsplit=1)[0].strip().lstrip('@')
|
||||
cmd = shortcut_line.split(maxsplit=1)[1].strip()
|
||||
shortcut_list.append({'occurrence': occurrence,
|
||||
'command': cmd})
|
||||
|
||||
# Add header row for parsing
|
||||
cleandata[:0] = ['minute hour day_of_month month day_of_week command']
|
||||
|
||||
if len(cleandata) > 1:
|
||||
cron_list = jc.parsers.universal.simple_table_parse(cleandata)
|
||||
|
||||
raw_output['schedule'] = cron_list
|
||||
|
||||
# Add shortcut entries back in
|
||||
for item in shortcut_list:
|
||||
raw_output['schedule'].append(item)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
273
jc/parsers/crontab_u.py
Normal file
273
jc/parsers/crontab_u.py
Normal file
@@ -0,0 +1,273 @@
|
||||
"""jc - JSON CLI output utility crontab file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --crontab-u as the first argument if the piped input is coming from a crontab file with User specified
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/crontab | jc --crontab-u -p
|
||||
{
|
||||
"variables": [
|
||||
{
|
||||
"name": "PATH",
|
||||
"value": "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
|
||||
},
|
||||
{
|
||||
"name": "SHELL",
|
||||
"value": "/bin/sh"
|
||||
}
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
"minute": [
|
||||
"25"
|
||||
],
|
||||
"hour": [
|
||||
"6"
|
||||
],
|
||||
"day_of_month": [
|
||||
"*"
|
||||
],
|
||||
"month": [
|
||||
"*"
|
||||
],
|
||||
"day_of_week": [
|
||||
"*"
|
||||
],
|
||||
"user": "root",
|
||||
"command": "test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )"
|
||||
},
|
||||
{
|
||||
"minute": [
|
||||
"47"
|
||||
],
|
||||
"hour": [
|
||||
"6"
|
||||
],
|
||||
"day_of_month": [
|
||||
"*"
|
||||
],
|
||||
"month": [
|
||||
"*"
|
||||
],
|
||||
"day_of_week": [
|
||||
"7"
|
||||
],
|
||||
"user": "root",
|
||||
"command": "test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )"
|
||||
},
|
||||
{
|
||||
"minute": [
|
||||
"52"
|
||||
],
|
||||
"hour": [
|
||||
"6"
|
||||
],
|
||||
"day_of_month": [
|
||||
"1"
|
||||
],
|
||||
"month": [
|
||||
"*"
|
||||
],
|
||||
"day_of_week": [
|
||||
"*"
|
||||
],
|
||||
"user": "root",
|
||||
"command": "test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
$ cat /etc/crontab | jc --crontab-u -p -r
|
||||
{
|
||||
"variables": [
|
||||
{
|
||||
"name": "PATH",
|
||||
"value": "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
|
||||
},
|
||||
{
|
||||
"name": "SHELL",
|
||||
"value": "/bin/sh"
|
||||
}
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
"minute": "25",
|
||||
"hour": "6",
|
||||
"day_of_month": "*",
|
||||
"month": "*",
|
||||
"day_of_week": "*",
|
||||
"user": "root",
|
||||
"command": "test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )"
|
||||
},
|
||||
{
|
||||
"minute": "47",
|
||||
"hour": "6",
|
||||
"day_of_month": "*",
|
||||
"month": "*",
|
||||
"day_of_week": "7",
|
||||
"user": "root",
|
||||
"command": "test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )"
|
||||
},
|
||||
{
|
||||
"minute": "52",
|
||||
"hour": "6",
|
||||
"day_of_month": "1",
|
||||
"month": "*",
|
||||
"day_of_week": "*",
|
||||
"user": "root",
|
||||
"command": "test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
"""
|
||||
import jc.utils
|
||||
import jc.parsers.universal
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'crontab file parser with user support'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Structured data with the following schema:
|
||||
|
||||
{
|
||||
"variables": [
|
||||
"name": string,
|
||||
"value": string
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
"occurrence" string,
|
||||
"minute": [
|
||||
string
|
||||
],
|
||||
"hour": [
|
||||
string
|
||||
],
|
||||
"day_of_month": [
|
||||
string
|
||||
],
|
||||
"month": [
|
||||
string
|
||||
],
|
||||
"day_of_week": [
|
||||
string
|
||||
],
|
||||
"occurrence": string,
|
||||
"user": string,
|
||||
"command": string
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
"""
|
||||
# put itmes in lists
|
||||
try:
|
||||
for entry in proc_data['schedule']:
|
||||
entry['minute'] = entry['minute'].split(',')
|
||||
entry['hour'] = entry['hour'].split(',')
|
||||
entry['day_of_month'] = entry['day_of_month'].split(',')
|
||||
entry['month'] = entry['month'].split(',')
|
||||
entry['day_of_week'] = entry['day_of_week'].split(',')
|
||||
except (KeyError):
|
||||
pass
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = {}
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
# Clear any commented lines
|
||||
for i, line in reversed(list(enumerate(cleandata))):
|
||||
if line.strip().find('#') == 0:
|
||||
cleandata.pop(i)
|
||||
|
||||
# Pop any variable assignment lines
|
||||
cron_var = []
|
||||
for i, line in reversed(list(enumerate(cleandata))):
|
||||
if line.find('=') != -1:
|
||||
var_line = cleandata.pop(i)
|
||||
var_name = var_line.split('=', maxsplit=1)[0].strip()
|
||||
var_value = var_line.split('=', maxsplit=1)[1].strip()
|
||||
cron_var.append({'name': var_name,
|
||||
'value': var_value})
|
||||
|
||||
raw_output['variables'] = cron_var
|
||||
|
||||
# Pop any shortcut lines
|
||||
shortcut_list = []
|
||||
for i, line in reversed(list(enumerate(cleandata))):
|
||||
if line.strip().startswith('@'):
|
||||
shortcut_line = cleandata.pop(i)
|
||||
occurrence = shortcut_line.split(maxsplit=1)[0].strip().lstrip('@')
|
||||
usr = shortcut_line.split(maxsplit=2)[1].strip()
|
||||
cmd = shortcut_line.split(maxsplit=2)[2].strip()
|
||||
shortcut_list.append({'occurrence': occurrence,
|
||||
'user': usr,
|
||||
'command': cmd})
|
||||
|
||||
# Add header row for parsing
|
||||
cleandata[:0] = ['minute hour day_of_month month day_of_week user command']
|
||||
|
||||
if len(cleandata) > 1:
|
||||
cron_list = jc.parsers.universal.simple_table_parse(cleandata)
|
||||
|
||||
raw_output['schedule'] = cron_list
|
||||
|
||||
# Add shortcut entries back in
|
||||
for item in shortcut_list:
|
||||
raw_output['schedule'].append(item)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
106
jc/parsers/df.py
106
jc/parsers/df.py
@@ -1,15 +1,20 @@
|
||||
"""jc - JSON CLI output utility df Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --df as the first argument if the piped input is coming from df
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin'
|
||||
|
||||
Examples:
|
||||
|
||||
$ df | jc --df -p
|
||||
[
|
||||
{
|
||||
"filesystem": "devtmpfs",
|
||||
"1k-blocks": 1918820,
|
||||
"1k_blocks": 1918820,
|
||||
"used": 0,
|
||||
"available": 1918820,
|
||||
"use_percent": 0,
|
||||
@@ -17,7 +22,7 @@ Examples:
|
||||
},
|
||||
{
|
||||
"filesystem": "tmpfs",
|
||||
"1k-blocks": 1930668,
|
||||
"1k_blocks": 1930668,
|
||||
"used": 0,
|
||||
"available": 1930668,
|
||||
"use_percent": 0,
|
||||
@@ -25,7 +30,7 @@ Examples:
|
||||
},
|
||||
{
|
||||
"filesystem": "tmpfs",
|
||||
"1k-blocks": 1930668,
|
||||
"1k_blocks": 1930668,
|
||||
"used": 11800,
|
||||
"available": 1918868,
|
||||
"use_percent": 1,
|
||||
@@ -38,7 +43,7 @@ Examples:
|
||||
[
|
||||
{
|
||||
"filesystem": "devtmpfs",
|
||||
"1k-blocks": "1918820",
|
||||
"1k_blocks": "1918820",
|
||||
"used": "0",
|
||||
"available": "1918820",
|
||||
"use_percent": "0%",
|
||||
@@ -46,7 +51,7 @@ Examples:
|
||||
},
|
||||
{
|
||||
"filesystem": "tmpfs",
|
||||
"1k-blocks": "1930668",
|
||||
"1k_blocks": "1930668",
|
||||
"used": "0",
|
||||
"available": "1930668",
|
||||
"use_percent": "0%",
|
||||
@@ -54,7 +59,7 @@ Examples:
|
||||
},
|
||||
{
|
||||
"filesystem": "tmpfs",
|
||||
"1k-blocks": "1930668",
|
||||
"1k_blocks": "1930668",
|
||||
"used": "11800",
|
||||
"available": "1918868",
|
||||
"use_percent": "1%",
|
||||
@@ -64,6 +69,21 @@ Examples:
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
import jc.parsers.universal
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'df command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin']
|
||||
magic_commands = ['df']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
@@ -76,36 +96,64 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"filesystem": string,
|
||||
"size": string,
|
||||
"1k-blocks": integer,
|
||||
"used": integer,
|
||||
"available": integer,
|
||||
"use_percent": integer,
|
||||
"mounted_on": string
|
||||
"filesystem": string,
|
||||
"size": string,
|
||||
"1k_blocks": integer,
|
||||
"512_blocks": integer,
|
||||
"used": integer,
|
||||
"available": integer,
|
||||
"capacity_percent": integer,
|
||||
"ifree": integer,
|
||||
"iused": integer,
|
||||
"use_percent": integer,
|
||||
"iused_percent": integer,
|
||||
"mounted_on": string
|
||||
}
|
||||
]
|
||||
"""
|
||||
|
||||
for entry in proc_data:
|
||||
# change any entry for key with '-blocks' in the name to int
|
||||
# change 'avail' to 'available'
|
||||
if 'avail' in entry:
|
||||
entry['available'] = entry.pop('avail')
|
||||
|
||||
# change 'use%' to 'use_percent'
|
||||
if 'use%' in entry:
|
||||
entry['use_percent'] = entry.pop('use%')
|
||||
|
||||
# change 'capacity' to 'capacity_percent'
|
||||
if 'capacity' in entry:
|
||||
entry['capacity_percent'] = entry.pop('capacity')
|
||||
|
||||
# change '%iused' to 'iused_percent'
|
||||
if '%iused' in entry:
|
||||
entry['iused_percent'] = entry.pop('%iused')
|
||||
|
||||
# change any entry for key with '_blocks' in the name to int
|
||||
for k in entry:
|
||||
if str(k).find('-blocks') != -1:
|
||||
if str(k).find('_blocks') != -1:
|
||||
try:
|
||||
blocks_int = int(entry[k])
|
||||
entry[k] = blocks_int
|
||||
except (ValueError):
|
||||
entry[k] = None
|
||||
|
||||
# remove percent sign from 'use_percent'
|
||||
# remove percent sign from 'use_percent', 'capacity_percent', and 'iused_percent'
|
||||
if 'use_percent' in entry:
|
||||
entry['use_percent'] = entry['use_percent'].rstrip('%')
|
||||
|
||||
# change used, available, and use_percent to int
|
||||
int_list = ['used', 'available', 'use_percent']
|
||||
if 'capacity_percent' in entry:
|
||||
entry['capacity_percent'] = entry['capacity_percent'].rstrip('%')
|
||||
|
||||
if 'iused_percent' in entry:
|
||||
entry['iused_percent'] = entry['iused_percent'].rstrip('%')
|
||||
|
||||
# change used, available, use_percent, capacity_percent, ifree, iused, iused_percent to int
|
||||
int_list = ['used', 'available', 'use_percent', 'capacity_percent', 'ifree', 'iused', 'iused_percent']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
@@ -129,23 +177,21 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
cleandata = data.splitlines()
|
||||
fix_headers = cleandata[0].lower().replace('avail ', 'available ')
|
||||
fix_headers = fix_headers.replace('use%', 'use_percent')
|
||||
fix_headers = fix_headers.replace('mounted on', 'mounted_on')
|
||||
headers = [h for h in ' '.join(fix_headers.strip().split()).split() if h]
|
||||
|
||||
raw_data = map(lambda s: s.strip().split(None, len(headers) - 1), cleandata[1:])
|
||||
raw_output = [dict(zip(headers, r)) for r in raw_data]
|
||||
# fix headers
|
||||
cleandata[0] = cleandata[0].lower()
|
||||
cleandata[0] = cleandata[0].replace('-', '_')
|
||||
cleandata[0] = cleandata[0].replace('mounted on', 'mounted_on')
|
||||
|
||||
# parse the data
|
||||
raw_output = jc.parsers.universal.sparse_table_parse(cleandata)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility dig Parser
|
||||
|
||||
Usage:
|
||||
|
||||
Specify --dig as the first argument if the piped input is coming from dig
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ dig cnn.com www.cnn.com @205.251.194.64 | jc --dig -p
|
||||
@@ -318,6 +323,20 @@ Examples:
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'dig command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'aix', 'freebsd', 'darwin']
|
||||
magic_commands = ['dig']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -328,7 +347,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -501,14 +520,11 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
152
jc/parsers/du.py
Normal file
152
jc/parsers/du.py
Normal file
@@ -0,0 +1,152 @@
|
||||
"""jc - JSON CLI output utility du Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --du as the first argument if the piped input is coming from du
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ du /usr | jc --du -p
|
||||
[
|
||||
{
|
||||
"size": 104608,
|
||||
"name": "/usr/bin"
|
||||
},
|
||||
{
|
||||
"size": 56,
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/_CodeSignature"
|
||||
},
|
||||
{
|
||||
"size": 0,
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/usr/local/standalone"
|
||||
},
|
||||
{
|
||||
"size": 0,
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/usr/local"
|
||||
},
|
||||
{
|
||||
"size": 0,
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/usr"
|
||||
},
|
||||
{
|
||||
"size": 1008,
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/dfu"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ du /usr | jc --du -p -r
|
||||
[
|
||||
{
|
||||
"size": "104608",
|
||||
"name": "/usr/bin"
|
||||
},
|
||||
{
|
||||
"size": "56",
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/_CodeSignature"
|
||||
},
|
||||
{
|
||||
"size": "0",
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/usr/local/standalone"
|
||||
},
|
||||
{
|
||||
"size": "0",
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/usr/local"
|
||||
},
|
||||
{
|
||||
"size": "0",
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/usr"
|
||||
},
|
||||
{
|
||||
"size": "1008",
|
||||
"name": "/usr/standalone/firmware/iBridge1_1Customer.bundle/Contents/Resources/Firmware/dfu"
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
import jc.parsers.universal
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'du command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'aix', 'freebsd']
|
||||
magic_commands = ['du']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"size": integer,
|
||||
"name": string
|
||||
}
|
||||
]
|
||||
"""
|
||||
int_list = ['size']
|
||||
for entry in proc_data:
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
key_int = int(entry[key])
|
||||
entry[key] = key_int
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
cleandata.insert(0, 'size name')
|
||||
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility env Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --env as the first argument if the piped input is coming from env
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ env | jc --env -p
|
||||
@@ -46,6 +51,20 @@ Examples:
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'env command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
magic_commands = ['env']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -56,7 +75,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -89,14 +108,11 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
Dictionary of raw structured data or
|
||||
list of dictionaries of processed structured data
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = {}
|
||||
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility foo Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --foo as the first argument if the piped input is coming from foo
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ foo | jc --foo -p
|
||||
@@ -14,6 +19,21 @@ Examples:
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'foo command parser'
|
||||
author = 'John Doe'
|
||||
author_email = 'johndoe@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
magic_commands = ['foo']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -24,7 +44,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -51,14 +71,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility free Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --free as the first argument if the piped input is coming from free
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ free | jc --free -p
|
||||
@@ -44,6 +49,21 @@ Examples:
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
import jc.parsers.universal
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'free command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['free']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
@@ -56,7 +76,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -96,28 +116,17 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
|
||||
# code adapted from Conor Heine at:
|
||||
# https://gist.github.com/cahna/43a1a3ff4d075bcd71f9d7120037a501
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
cleandata = data.splitlines()
|
||||
headers = [h for h in ' '.join(cleandata[0].lower().strip().split()).split() if h]
|
||||
headers.insert(0, "type")
|
||||
cleandata[0] = cleandata[0].lower()
|
||||
cleandata[0] = cleandata[0].replace('buff/cache', 'buff_cache')
|
||||
cleandata[0] = 'type ' + cleandata[0]
|
||||
|
||||
# clean up 'buff/cache' header
|
||||
# even though forward slash in a key is valid json, it can make things difficult
|
||||
headers = ['buff_cache' if x == 'buff/cache' else x for x in headers]
|
||||
|
||||
raw_data = map(lambda s: s.strip().split(None, len(headers) - 1), cleandata[1:])
|
||||
raw_output = [dict(zip(headers, r)) for r in raw_data]
|
||||
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
|
||||
|
||||
for entry in raw_output:
|
||||
entry['type'] = entry['type'].rstrip(':')
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility fstab Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --fstab as the first argument if the piped input is coming from a fstab file
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/fstab | jc --fstab -p
|
||||
@@ -64,6 +69,19 @@ Examples:
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'fstab file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -74,7 +92,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -112,14 +130,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
@@ -1,26 +1,31 @@
|
||||
"""jc - JSON CLI output utility history Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --history as the first argument if the piped input is coming from history
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ history | jc --history -p
|
||||
[
|
||||
{
|
||||
"line": "118",
|
||||
"line": 118,
|
||||
"command": "sleep 100"
|
||||
},
|
||||
{
|
||||
"line": "119",
|
||||
"line": 119,
|
||||
"command": "ls /bin"
|
||||
},
|
||||
{
|
||||
"line": "120",
|
||||
"line": 120,
|
||||
"command": "echo \"hello\""
|
||||
},
|
||||
{
|
||||
"line": "121",
|
||||
"line": 121,
|
||||
"command": "docker images"
|
||||
},
|
||||
...
|
||||
@@ -38,6 +43,19 @@ Examples:
|
||||
import jc
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'history command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -48,11 +66,11 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"line": string,
|
||||
"line": integer,
|
||||
"command": string
|
||||
}
|
||||
]
|
||||
@@ -66,6 +84,16 @@ def process(proc_data):
|
||||
proc_line['command'] = v
|
||||
processed.append(proc_line)
|
||||
|
||||
for entry in processed:
|
||||
int_list = ['line']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
key_int = int(entry[key])
|
||||
entry[key] = key_int
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
return processed
|
||||
|
||||
|
||||
@@ -81,14 +109,11 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
Dictionary of raw structured data or
|
||||
list of dictionaries of processed structured data
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = {}
|
||||
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility hosts Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --hosts as the first argument if the piped input is coming from a hosts file
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/hosts | jc --hosts -p
|
||||
@@ -55,6 +60,19 @@ Examples:
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = '/etc/hosts file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -65,7 +83,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -93,14 +111,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
215
jc/parsers/id.py
Normal file
215
jc/parsers/id.py
Normal file
@@ -0,0 +1,215 @@
|
||||
"""jc - JSON CLI output utility id Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --id as the first argument if the piped input is coming from id
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ id | jc --id -p
|
||||
{
|
||||
"uid": {
|
||||
"id": 1000,
|
||||
"name": "joeuser"
|
||||
},
|
||||
"gid": {
|
||||
"id": 1000,
|
||||
"name": "joeuser"
|
||||
},
|
||||
"groups": [
|
||||
{
|
||||
"id": 1000,
|
||||
"name": "joeuser"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "wheel"
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"user": "unconfined_u",
|
||||
"role": "unconfined_r",
|
||||
"type": "unconfined_t",
|
||||
"level": "s0-s0:c0.c1023"
|
||||
}
|
||||
}
|
||||
|
||||
$ id | jc --id -p -r
|
||||
{
|
||||
"uid": {
|
||||
"id": "1000",
|
||||
"name": "joeuser"
|
||||
},
|
||||
"gid": {
|
||||
"id": "1000",
|
||||
"name": "joeuser"
|
||||
},
|
||||
"groups": [
|
||||
{
|
||||
"id": "1000",
|
||||
"name": "joeuser"
|
||||
},
|
||||
{
|
||||
"id": "10",
|
||||
"name": "wheel"
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"user": "unconfined_u",
|
||||
"role": "unconfined_r",
|
||||
"type": "unconfined_t",
|
||||
"level": "s0-s0:c0.c1023"
|
||||
}
|
||||
}
|
||||
"""
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'id command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'aix', 'freebsd']
|
||||
magic_commands = ['id']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Structured data with the following schema:
|
||||
|
||||
{
|
||||
"uid": {
|
||||
"id": integer,
|
||||
"name": string
|
||||
},
|
||||
"gid": {
|
||||
"id": integer,
|
||||
"name": string
|
||||
},
|
||||
"groups": [
|
||||
{
|
||||
"id": integer,
|
||||
"name": string
|
||||
},
|
||||
{
|
||||
"id": integer,
|
||||
"name": string
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"user": string,
|
||||
"role": string,
|
||||
"type": string,
|
||||
"level": string
|
||||
}
|
||||
}
|
||||
"""
|
||||
if 'uid' in proc_data:
|
||||
if 'id' in proc_data['uid']:
|
||||
try:
|
||||
proc_data['uid']['id'] = int(proc_data['uid']['id'])
|
||||
except (ValueError):
|
||||
proc_data['uid']['id'] = None
|
||||
|
||||
if 'gid' in proc_data:
|
||||
if 'id' in proc_data['gid']:
|
||||
try:
|
||||
proc_data['gid']['id'] = int(proc_data['gid']['id'])
|
||||
except (ValueError):
|
||||
proc_data['gid']['id'] = None
|
||||
|
||||
if 'groups' in proc_data:
|
||||
for group in proc_data['groups']:
|
||||
if 'id' in group:
|
||||
try:
|
||||
group['id'] = int(group['id'])
|
||||
except (ValueError):
|
||||
group['id'] = None
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = {}
|
||||
cleandata = data.split()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
for section in cleandata:
|
||||
if section.startswith('uid'):
|
||||
uid_parsed = section.replace('(', '=').replace(')', '=')
|
||||
uid_parsed = uid_parsed.split('=')
|
||||
raw_output['uid'] = {}
|
||||
raw_output['uid']['id'] = uid_parsed[1]
|
||||
raw_output['uid']['name'] = uid_parsed[2]
|
||||
|
||||
if section.startswith('gid'):
|
||||
gid_parsed = section.replace('(', '=').replace(')', '=')
|
||||
gid_parsed = gid_parsed.split('=')
|
||||
raw_output['gid'] = {}
|
||||
raw_output['gid']['id'] = gid_parsed[1]
|
||||
raw_output['gid']['name'] = gid_parsed[2]
|
||||
|
||||
if section.startswith('groups'):
|
||||
groups_parsed = section.replace('(', '=').replace(')', '=')
|
||||
groups_parsed = groups_parsed.replace('groups=', '')
|
||||
groups_parsed = groups_parsed.split(',')
|
||||
raw_output['groups'] = []
|
||||
|
||||
for group in groups_parsed:
|
||||
group_dict = {}
|
||||
grp_parsed = group.split('=')
|
||||
group_dict['id'] = grp_parsed[0]
|
||||
group_dict['name'] = grp_parsed[1]
|
||||
raw_output['groups'].append(group_dict)
|
||||
|
||||
if section.startswith('context'):
|
||||
context_parsed = section.replace('context=', '')
|
||||
context_parsed = context_parsed.split(':', maxsplit=3)
|
||||
raw_output['context'] = {}
|
||||
raw_output['context']['user'] = context_parsed[0]
|
||||
raw_output['context']['role'] = context_parsed[1]
|
||||
raw_output['context']['type'] = context_parsed[2]
|
||||
raw_output['context']['level'] = context_parsed[3]
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
@@ -1,10 +1,15 @@
|
||||
"""jc - JSON CLI output utility ifconfig Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ifconfig as the first argument if the piped input is coming from ifconfig
|
||||
|
||||
no ifconfig options are supported.
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'aix', 'freebsd', 'darwin'
|
||||
|
||||
Examples:
|
||||
|
||||
$ ifconfig | jc --ifconfig -p
|
||||
@@ -12,22 +17,29 @@ Examples:
|
||||
{
|
||||
"name": "ens33",
|
||||
"flags": 4163,
|
||||
"state": "UP,BROADCAST,RUNNING,MULTICAST",
|
||||
"state": [
|
||||
"UP",
|
||||
"BROADCAST",
|
||||
"RUNNING",
|
||||
"MULTICAST"
|
||||
],
|
||||
"mtu": 1500,
|
||||
"ipv4_addr": "192.168.71.138",
|
||||
"ipv4_addr": "192.168.71.137",
|
||||
"ipv4_mask": "255.255.255.0",
|
||||
"ipv4_bcast": "192.168.71.255",
|
||||
"ipv6_addr": "fe80::c1cb:715d:bc3e:b8a0",
|
||||
"ipv6_mask": 64,
|
||||
"ipv6_scope": "link",
|
||||
"ipv6_scope": "0x20",
|
||||
"mac_addr": "00:0c:29:3b:58:0e",
|
||||
"type": "Ethernet",
|
||||
"rx_packets": 6374,
|
||||
"rx_packets": 8061,
|
||||
"rx_bytes": 1514413,
|
||||
"rx_errors": 0,
|
||||
"rx_dropped": 0,
|
||||
"rx_overruns": 0,
|
||||
"rx_frame": 0,
|
||||
"tx_packets": 3707,
|
||||
"tx_packets": 4502,
|
||||
"tx_bytes": 866622,
|
||||
"tx_errors": 0,
|
||||
"tx_dropped": 0,
|
||||
"tx_overruns": 0,
|
||||
@@ -38,22 +50,28 @@ Examples:
|
||||
{
|
||||
"name": "lo",
|
||||
"flags": 73,
|
||||
"state": "UP,LOOPBACK,RUNNING",
|
||||
"state": [
|
||||
"UP",
|
||||
"LOOPBACK",
|
||||
"RUNNING"
|
||||
],
|
||||
"mtu": 65536,
|
||||
"ipv4_addr": "127.0.0.1",
|
||||
"ipv4_mask": "255.0.0.0",
|
||||
"ipv4_bcast": null,
|
||||
"ipv6_addr": "::1",
|
||||
"ipv6_mask": 128,
|
||||
"ipv6_scope": "host",
|
||||
"ipv6_scope": "0x10",
|
||||
"mac_addr": null,
|
||||
"type": "Local Loopback",
|
||||
"rx_packets": 81,
|
||||
"rx_packets": 73,
|
||||
"rx_bytes": 6009,
|
||||
"rx_errors": 0,
|
||||
"rx_dropped": 0,
|
||||
"rx_overruns": 0,
|
||||
"rx_frame": 0,
|
||||
"tx_packets": 81,
|
||||
"tx_packets": 73,
|
||||
"tx_bytes": 6009,
|
||||
"tx_errors": 0,
|
||||
"tx_dropped": 0,
|
||||
"tx_overruns": 0,
|
||||
@@ -70,20 +88,22 @@ Examples:
|
||||
"flags": "4163",
|
||||
"state": "UP,BROADCAST,RUNNING,MULTICAST",
|
||||
"mtu": "1500",
|
||||
"ipv4_addr": "192.168.71.135",
|
||||
"ipv4_addr": "192.168.71.137",
|
||||
"ipv4_mask": "255.255.255.0",
|
||||
"ipv4_bcast": "192.168.71.255",
|
||||
"ipv6_addr": "fe80::c1cb:715d:bc3e:b8a0",
|
||||
"ipv6_mask": "64",
|
||||
"ipv6_scope": "link",
|
||||
"ipv6_scope": "0x20",
|
||||
"mac_addr": "00:0c:29:3b:58:0e",
|
||||
"type": "Ethernet",
|
||||
"rx_packets": "26348",
|
||||
"rx_packets": "8061",
|
||||
"rx_bytes": "1514413",
|
||||
"rx_errors": "0",
|
||||
"rx_dropped": "0",
|
||||
"rx_overruns": "0",
|
||||
"rx_frame": "0",
|
||||
"tx_packets": "5308",
|
||||
"tx_packets": "4502",
|
||||
"tx_bytes": "866622",
|
||||
"tx_errors": "0",
|
||||
"tx_dropped": "0",
|
||||
"tx_overruns": "0",
|
||||
@@ -101,15 +121,17 @@ Examples:
|
||||
"ipv4_bcast": null,
|
||||
"ipv6_addr": "::1",
|
||||
"ipv6_mask": "128",
|
||||
"ipv6_scope": "host",
|
||||
"ipv6_scope": "0x10",
|
||||
"mac_addr": null,
|
||||
"type": "Local Loopback",
|
||||
"rx_packets": "64",
|
||||
"rx_packets": "73",
|
||||
"rx_bytes": "6009",
|
||||
"rx_errors": "0",
|
||||
"rx_dropped": "0",
|
||||
"rx_overruns": "0",
|
||||
"rx_frame": "0",
|
||||
"tx_packets": "64",
|
||||
"tx_packets": "73",
|
||||
"tx_bytes": "6009",
|
||||
"tx_errors": "0",
|
||||
"tx_dropped": "0",
|
||||
"tx_overruns": "0",
|
||||
@@ -123,6 +145,21 @@ import jc.utils
|
||||
from ifconfigparser import IfconfigParser
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.5'
|
||||
description = 'ifconfig command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
details = 'Using ifconfig-parser package from https://github.com/KnightWhoSayNi/ifconfig-parser'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'aix', 'freebsd', 'darwin']
|
||||
magic_commands = ['ifconfig']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -133,13 +170,15 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"name": string,
|
||||
"flags": integer,
|
||||
"state": string,
|
||||
"state": [
|
||||
string
|
||||
],
|
||||
"mtu": integer,
|
||||
"ipv4_addr": string,
|
||||
"ipv4_mask": string,
|
||||
@@ -150,11 +189,13 @@ def process(proc_data):
|
||||
"mac_addr": string,
|
||||
"type": string,
|
||||
"rx_packets": integer,
|
||||
"rx_bytes": integer,
|
||||
"rx_errors": integer,
|
||||
"rx_dropped": integer,
|
||||
"rx_overruns": integer,
|
||||
"rx_frame": integer,
|
||||
"tx_packets": integer,
|
||||
"tx_bytes": integer,
|
||||
"tx_errors": integer,
|
||||
"tx_dropped": integer,
|
||||
"tx_overruns": integer,
|
||||
@@ -165,8 +206,8 @@ def process(proc_data):
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
int_list = ['flags', 'mtu', 'ipv6_mask', 'rx_packets', 'rx_errors', 'rx_dropped', 'rx_overruns',
|
||||
'rx_frame', 'tx_packets', 'tx_errors', 'tx_dropped', 'tx_overruns', 'tx_carrier',
|
||||
int_list = ['flags', 'mtu', 'ipv6_mask', 'rx_packets', 'rx_bytes', 'rx_errors', 'rx_dropped', 'rx_overruns',
|
||||
'rx_frame', 'tx_packets', 'tx_bytes', 'tx_errors', 'tx_dropped', 'tx_overruns', 'tx_carrier',
|
||||
'tx_collisions', 'metric']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
@@ -176,6 +217,25 @@ def process(proc_data):
|
||||
except (ValueError, TypeError):
|
||||
entry[key] = None
|
||||
|
||||
# convert OSX-style subnet mask to dotted quad
|
||||
if 'ipv4_mask' in entry:
|
||||
try:
|
||||
if entry['ipv4_mask'].find('0x') == 0:
|
||||
new_mask = entry['ipv4_mask']
|
||||
new_mask = new_mask.lstrip('0x')
|
||||
new_mask = '.'.join(str(int(i, 16)) for i in [new_mask[i:i + 2] for i in range(0, len(new_mask), 2)])
|
||||
entry['ipv4_mask'] = new_mask
|
||||
except (ValueError, TypeError, AttributeError):
|
||||
pass
|
||||
|
||||
# convert state value to an array
|
||||
if 'state' in entry:
|
||||
try:
|
||||
new_state = entry['state'].split(',')
|
||||
entry['state'] = new_state
|
||||
except (ValueError, TypeError, AttributeError):
|
||||
pass
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
@@ -184,21 +244,17 @@ def parse(data, raw=False, quiet=False):
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'aix', 'freebsd']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
|
||||
|
||||
112
jc/parsers/ini.py
Normal file
112
jc/parsers/ini.py
Normal file
@@ -0,0 +1,112 @@
|
||||
"""jc - JSON CLI output utility INI Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ini as the first argument if the piped input is coming from an INI file
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat example.ini
|
||||
[DEFAULT]
|
||||
ServerAliveInterval = 45
|
||||
Compression = yes
|
||||
CompressionLevel = 9
|
||||
ForwardX11 = yes
|
||||
|
||||
[bitbucket.org]
|
||||
User = hg
|
||||
|
||||
[topsecret.server.com]
|
||||
Port = 50022
|
||||
ForwardX11 = no
|
||||
|
||||
$ cat example.ini | jc --ini -p
|
||||
{
|
||||
"bitbucket.org": {
|
||||
"serveraliveinterval": "45",
|
||||
"compression": "yes",
|
||||
"compressionlevel": "9",
|
||||
"forwardx11": "yes",
|
||||
"user": "hg"
|
||||
},
|
||||
"topsecret.server.com": {
|
||||
"serveraliveinterval": "45",
|
||||
"compression": "yes",
|
||||
"compressionlevel": "9",
|
||||
"forwardx11": "no",
|
||||
"port": "50022"
|
||||
}
|
||||
}
|
||||
"""
|
||||
import jc.utils
|
||||
import configparser
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'INI file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
details = 'Using configparser from the standard library'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary representing an ini document:
|
||||
|
||||
{
|
||||
ini document converted to a dictionary
|
||||
see configparser standard library documentation for more details
|
||||
}
|
||||
"""
|
||||
|
||||
# No further processing
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary representing the ini file
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = {}
|
||||
|
||||
if data:
|
||||
ini = configparser.ConfigParser()
|
||||
ini.read_string(data)
|
||||
raw_output = {s: dict(ini.items(s)) for s in ini.sections()}
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
@@ -1,10 +1,15 @@
|
||||
"""jc - JSON CLI output utility ipables Parser
|
||||
|
||||
Usage:
|
||||
|
||||
Specify --iptables as the first argument if the piped input is coming from iptables
|
||||
|
||||
Supports -vLn and --line-numbers for all tables
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ sudo iptables --line-numbers -v -L -t nat | jc --iptables -p
|
||||
@@ -128,6 +133,20 @@ Examples:
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'iptables command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['iptables']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -138,8 +157,8 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"chain": string,
|
||||
@@ -215,14 +234,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
chain = {}
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
"""jc - JSON CLI output utility jobs Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --jobs as the first argument if the piped input is coming from jobs
|
||||
|
||||
Also supports the -l option
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Example:
|
||||
|
||||
$ jobs -l | jc --jobs -p
|
||||
@@ -71,6 +76,20 @@ import string
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'jobs command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
magic_commands = ['jobs']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -81,7 +100,8 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"job_number": integer,
|
||||
@@ -117,14 +137,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
"""jc - JSON CLI output utility ls Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ls as the first argument if the piped input is coming from ls
|
||||
|
||||
ls options supported:
|
||||
- None
|
||||
- la
|
||||
- h file sizes will be available in text form with -r but larger file sizes
|
||||
with human readable suffixes will be converted to Null in default view
|
||||
since the parser attempts to convert this field to an integer.
|
||||
- laR
|
||||
--time-style=full-iso
|
||||
- h file sizes will be available in text form with -r but larger file sizes
|
||||
with human readable suffixes will be converted to Null in default view
|
||||
since the parser attempts to convert this field to an integer.
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -138,6 +144,20 @@ import re
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'ls command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
magic_commands = ['ls']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -148,13 +168,14 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"filename": string,
|
||||
"flags": string,
|
||||
"links": integer,
|
||||
"parent": string,
|
||||
"owner": string,
|
||||
"group": string,
|
||||
"size": integer,
|
||||
@@ -188,35 +209,49 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
|
||||
linedata = data.splitlines()
|
||||
|
||||
# Delete first line if it starts with 'total'
|
||||
# Delete first line if it starts with 'total 1234'
|
||||
if linedata:
|
||||
if linedata[0].find('total') == 0:
|
||||
if re.match('^total [0-9]+', linedata[0]):
|
||||
linedata.pop(0)
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, linedata))
|
||||
parent = ''
|
||||
next_is_parent = False
|
||||
|
||||
if cleandata:
|
||||
# Look for parent line if glob or -R is used
|
||||
if not re.match('^[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', linedata[0]) \
|
||||
and linedata[0].endswith(':'):
|
||||
parent = linedata.pop(0)[:-1]
|
||||
# Pop following total line
|
||||
linedata.pop(0)
|
||||
|
||||
if linedata:
|
||||
# Check if -l was used to parse extra data
|
||||
if re.match('^[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', cleandata[0]):
|
||||
for entry in cleandata:
|
||||
if re.match('^[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', linedata[0]):
|
||||
for entry in linedata:
|
||||
output_line = {}
|
||||
|
||||
parsed_line = entry.split(maxsplit=8)
|
||||
|
||||
if not re.match('^[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', entry) \
|
||||
and entry.endswith(':'):
|
||||
parent = entry[:-1]
|
||||
continue
|
||||
|
||||
if re.match('^total [0-9]+', entry):
|
||||
continue
|
||||
|
||||
if entry == '':
|
||||
continue
|
||||
|
||||
# split filenames and links
|
||||
filename_field = parsed_line[8].split(' -> ')
|
||||
|
||||
@@ -226,6 +261,9 @@ def parse(data, raw=False, quiet=False):
|
||||
if len(filename_field) > 1:
|
||||
output_line['link_to'] = filename_field[1]
|
||||
|
||||
if parent:
|
||||
output_line['parent'] = parent
|
||||
|
||||
output_line['flags'] = parsed_line[0]
|
||||
output_line['links'] = parsed_line[1]
|
||||
output_line['owner'] = parsed_line[2]
|
||||
@@ -234,9 +272,23 @@ def parse(data, raw=False, quiet=False):
|
||||
output_line['date'] = ' '.join(parsed_line[5:8])
|
||||
raw_output.append(output_line)
|
||||
else:
|
||||
for entry in cleandata:
|
||||
for entry in linedata:
|
||||
output_line = {}
|
||||
|
||||
if entry == '':
|
||||
next_is_parent = True
|
||||
continue
|
||||
|
||||
if next_is_parent:
|
||||
parent = entry[:-1]
|
||||
next_is_parent = False
|
||||
continue
|
||||
|
||||
output_line['filename'] = entry
|
||||
|
||||
if parent:
|
||||
output_line['parent'] = parent
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility lsblk Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --lsblk as the first argument if the piped input is coming from lsblk
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ lsblk | jc --lsblk -p
|
||||
@@ -206,8 +211,22 @@ Examples:
|
||||
...
|
||||
]
|
||||
"""
|
||||
import string
|
||||
import jc.utils
|
||||
import jc.parsers.universal
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.3'
|
||||
description = 'lsblk command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['lsblk']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
@@ -220,7 +239,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -303,82 +322,25 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
# unicode \u2063 = invisible separator and should not be seen in lsblk output
|
||||
delim = '\u2063'
|
||||
|
||||
raw_output = []
|
||||
linedata = data.splitlines()
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, linedata))
|
||||
cleandata = data.splitlines()
|
||||
|
||||
header_text = cleandata.pop(0).lower()
|
||||
header_text = header_text.replace(':', '_')
|
||||
header_text = header_text.replace('-', '_')
|
||||
header_text = header_text + ' '
|
||||
cleandata[0] = cleandata[0].lower()
|
||||
cleandata[0] = cleandata[0].replace(':', '_')
|
||||
cleandata[0] = cleandata[0].replace('-', '_')
|
||||
|
||||
header_list = header_text.split()
|
||||
raw_output = jc.parsers.universal.sparse_table_parse(cleandata)
|
||||
|
||||
# find each column index and end position
|
||||
header_search = [header_list[0]]
|
||||
for h in header_list[1:]:
|
||||
header_search.append(' ' + h + ' ')
|
||||
|
||||
header_spec_list = []
|
||||
for i, column in enumerate(header_list[0:len(header_list) - 1]):
|
||||
header_spec = {
|
||||
'name': column,
|
||||
'end': header_text.find(header_search[i + 1])
|
||||
}
|
||||
|
||||
header_spec_list.append(header_spec)
|
||||
|
||||
# parse lines
|
||||
if cleandata:
|
||||
for entry in cleandata:
|
||||
output_line = {}
|
||||
|
||||
# insert new separator since data can contain spaces
|
||||
for col in reversed(header_list):
|
||||
# find the right header_spec
|
||||
for h_spec in header_spec_list:
|
||||
if h_spec['name'] == col:
|
||||
h_end = h_spec['end']
|
||||
# check if the location contains whitespace. if not
|
||||
# then move to the left until a space is found
|
||||
while h_end > 0 and entry[h_end] not in string.whitespace:
|
||||
h_end -= 1
|
||||
|
||||
# insert custom delimiter
|
||||
entry = entry[:h_end] + delim + entry[h_end + 1:]
|
||||
|
||||
# create the entry list from the new custom delimiter
|
||||
entry_list = entry.split(delim, maxsplit=len(header_list) - 1)
|
||||
|
||||
# clean up leading and trailing spaces in entry
|
||||
clean_entry_list = []
|
||||
for col in entry_list:
|
||||
clean_entry = col.strip().rstrip()
|
||||
if clean_entry == '':
|
||||
clean_entry = None
|
||||
|
||||
clean_entry_list.append(clean_entry)
|
||||
|
||||
output_line = dict(zip(header_list, clean_entry_list))
|
||||
raw_output.append(output_line)
|
||||
|
||||
# clean up non-ascii characters, if any
|
||||
for entry in raw_output:
|
||||
entry['name'] = entry['name'].encode('ascii', errors='ignore').decode()
|
||||
# clean up non-ascii characters, if any
|
||||
for entry in raw_output:
|
||||
entry['name'] = entry['name'].encode('ascii', errors='ignore').decode()
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility lsmod Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --lsmod as the first argument if the piped input is coming from lsmod
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ lsmod | jc --lsmod -p
|
||||
@@ -98,6 +103,21 @@ Examples:
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
import jc.parsers.universal
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'lsmod command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['lsmod']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
@@ -110,7 +130,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -149,23 +169,15 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
|
||||
# code adapted from Conor Heine at:
|
||||
# https://gist.github.com/cahna/43a1a3ff4d075bcd71f9d7120037a501
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
cleandata = data.splitlines()
|
||||
headers = [h for h in ' '.join(cleandata[0].lower().strip().split()).split() if h]
|
||||
cleandata[0] = cleandata[0].lower()
|
||||
|
||||
raw_data = map(lambda s: s.strip().split(None, len(headers) - 1), cleandata[1:])
|
||||
raw_output = [dict(zip(headers, r)) for r in raw_data]
|
||||
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
|
||||
|
||||
for mod in raw_output:
|
||||
if 'by' in mod:
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility lsof Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --lsof as the first argument if the piped input is coming from lsof
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ sudo lsof | jc --lsof -p
|
||||
@@ -87,8 +92,22 @@ Examples:
|
||||
...
|
||||
]
|
||||
"""
|
||||
import string
|
||||
import jc.utils
|
||||
import jc.parsers.universal
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'lsof command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['lsof']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
@@ -101,7 +120,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -143,14 +162,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
|
||||
@@ -160,7 +175,12 @@ def parse(data, raw=False, quiet=False):
|
||||
cleandata = list(filter(None, linedata))
|
||||
|
||||
if cleandata:
|
||||
cleandata[0] = cleandata[0].lower()
|
||||
cleandata[0] = cleandata[0].replace('/', '_')
|
||||
|
||||
raw_output = jc.parsers.universal.sparse_table_parse(cleandata)
|
||||
|
||||
'''
|
||||
# find column value of last character of each header
|
||||
header_text = cleandata.pop(0).lower()
|
||||
|
||||
@@ -199,6 +219,7 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
output_line = dict(zip(headers, fixed_line))
|
||||
raw_output.append(output_line)
|
||||
'''
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility mount Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --mount as the first argument if the piped input is coming from mount
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin'
|
||||
|
||||
Example:
|
||||
|
||||
$ mount | jc --mount -p
|
||||
@@ -50,6 +55,20 @@ Example:
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'mount command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin']
|
||||
magic_commands = ['mount']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -60,8 +79,8 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"filesystem": string,
|
||||
@@ -77,6 +96,51 @@ def process(proc_data):
|
||||
return proc_data
|
||||
|
||||
|
||||
def osx_parse(data):
|
||||
output = []
|
||||
|
||||
for entry in data:
|
||||
output_line = {}
|
||||
|
||||
filesystem = entry.split(' on ')
|
||||
filesystem = filesystem[0]
|
||||
output_line['filesystem'] = filesystem
|
||||
|
||||
mount_point = entry.split(' on ')
|
||||
mount_point = mount_point[1].split(' (')
|
||||
mount_point = mount_point[0]
|
||||
output_line['mount_point'] = mount_point
|
||||
|
||||
options = entry.split('(', maxsplit=1)
|
||||
options = options[1].rstrip(')')
|
||||
options = options.split(', ')
|
||||
output_line['options'] = options
|
||||
|
||||
output.append(output_line)
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def linux_parse(data):
|
||||
output = []
|
||||
|
||||
for entry in data:
|
||||
output_line = {}
|
||||
parsed_line = entry.split()
|
||||
|
||||
output_line['filesystem'] = parsed_line[0]
|
||||
output_line['mount_point'] = parsed_line[2]
|
||||
output_line['type'] = parsed_line[4]
|
||||
|
||||
options = parsed_line[5].lstrip('(').rstrip(')').split(',')
|
||||
|
||||
output_line['options'] = options
|
||||
|
||||
output.append(output_line)
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
@@ -89,16 +153,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
|
||||
raw_output = []
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
linedata = data.splitlines()
|
||||
|
||||
@@ -106,19 +164,12 @@ def parse(data, raw=False, quiet=False):
|
||||
cleandata = list(filter(None, linedata))
|
||||
|
||||
if cleandata:
|
||||
for entry in cleandata:
|
||||
output_line = {}
|
||||
parsed_line = entry.split()
|
||||
# check for OSX output
|
||||
if cleandata[0].find(' type ') == -1:
|
||||
raw_output = osx_parse(cleandata)
|
||||
|
||||
output_line['filesystem'] = parsed_line[0]
|
||||
output_line['mount_point'] = parsed_line[2]
|
||||
output_line['type'] = parsed_line[4]
|
||||
|
||||
access = parsed_line[5].lstrip('(').rstrip(')').split(',')
|
||||
|
||||
output_line['options'] = access
|
||||
|
||||
raw_output.append(output_line)
|
||||
else:
|
||||
raw_output = linux_parse(cleandata)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility netstat Parser
|
||||
|
||||
Usage:
|
||||
|
||||
Specify --netstat as the first argument if the piped input is coming from netstat
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ sudo netstat -apee | jc --netstat -p
|
||||
@@ -307,6 +312,20 @@ import string
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.2'
|
||||
description = 'netstat command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['netstat']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -317,7 +336,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -506,14 +525,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
cleandata = data.splitlines()
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
117
jc/parsers/pip_list.py
Normal file
117
jc/parsers/pip_list.py
Normal file
@@ -0,0 +1,117 @@
|
||||
"""jc - JSON CLI output utility pip-list Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --pip-list as the first argument if the piped input is coming from pip list
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ pip list | jc --pip-list -p
|
||||
[
|
||||
{
|
||||
"package": "ansible",
|
||||
"version": "2.8.5"
|
||||
},
|
||||
{
|
||||
"package": "antlr4-python3-runtime",
|
||||
"version": "4.7.2"
|
||||
},
|
||||
{
|
||||
"package": "asn1crypto",
|
||||
"version": "0.24.0"
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
import jc.parsers.universal
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'pip list command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
magic_commands = ['pip list', 'pip3 list']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"package": string,
|
||||
"version": string,
|
||||
"location": string
|
||||
}
|
||||
]
|
||||
"""
|
||||
# no further processing
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
|
||||
linedata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, linedata))
|
||||
|
||||
# detect legacy output type
|
||||
if cleandata[0].find(' (') != -1:
|
||||
for row in cleandata:
|
||||
raw_output.append({'package': row.split(' (')[0],
|
||||
'version': row.split(' (')[1].rstrip(')')})
|
||||
|
||||
# otherwise normal table output
|
||||
else:
|
||||
# clear separator line
|
||||
for i, line in reversed(list(enumerate(cleandata))):
|
||||
if line.find('---') != -1:
|
||||
cleandata.pop(i)
|
||||
|
||||
cleandata[0] = cleandata[0].lower()
|
||||
|
||||
if cleandata:
|
||||
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
135
jc/parsers/pip_show.py
Normal file
135
jc/parsers/pip_show.py
Normal file
@@ -0,0 +1,135 @@
|
||||
"""jc - JSON CLI output utility pip-show Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --pip-show as the first argument if the piped input is coming from pip show
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ pip show wrapt jc wheel | jc --pip-show -p
|
||||
[
|
||||
{
|
||||
"name": "wrapt",
|
||||
"version": "1.11.2",
|
||||
"summary": "Module for decorators, wrappers and monkey patching.",
|
||||
"home_page": "https://github.com/GrahamDumpleton/wrapt",
|
||||
"author": "Graham Dumpleton",
|
||||
"author_email": "Graham.Dumpleton@gmail.com",
|
||||
"license": "BSD",
|
||||
"location": "/usr/local/lib/python3.7/site-packages",
|
||||
"requires": null,
|
||||
"required_by": "astroid"
|
||||
},
|
||||
{
|
||||
"name": "wheel",
|
||||
"version": "0.33.4",
|
||||
"summary": "A built-package format for Python.",
|
||||
"home_page": "https://github.com/pypa/wheel",
|
||||
"author": "Daniel Holth",
|
||||
"author_email": "dholth@fastmail.fm",
|
||||
"license": "MIT",
|
||||
"location": "/usr/local/lib/python3.7/site-packages",
|
||||
"requires": null,
|
||||
"required_by": null
|
||||
}
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'pip show command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
magic_commands = ['pip show', 'pip3 show']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"name": string,
|
||||
"version": string,
|
||||
"summary": string,
|
||||
"home_page": string,
|
||||
"author": string,
|
||||
"author_email": string,
|
||||
"license": string,
|
||||
"location": string,
|
||||
"requires": string,
|
||||
"required_by": string
|
||||
}
|
||||
]
|
||||
|
||||
"""
|
||||
# no further processing
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
package = {}
|
||||
|
||||
linedata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, linedata))
|
||||
|
||||
if cleandata:
|
||||
for row in cleandata:
|
||||
if row.startswith('---'):
|
||||
raw_output.append(package)
|
||||
package = {}
|
||||
continue
|
||||
|
||||
item_key = row.split(': ', maxsplit=1)[0].lower().replace('-', '_')
|
||||
item_value = row.split(': ', maxsplit=1)[1]
|
||||
|
||||
if item_value == '':
|
||||
item_value = None
|
||||
|
||||
package.update({item_key: item_value})
|
||||
|
||||
raw_output.append(package)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
@@ -1,12 +1,17 @@
|
||||
"""jc - JSON CLI output utility ps Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ps as the first argument if the piped input is coming from ps
|
||||
|
||||
ps options supported:
|
||||
- ef
|
||||
- axu
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ ps -ef | jc --ps -p
|
||||
@@ -168,6 +173,21 @@ Examples:
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
import jc.parsers.universal
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'ps command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
magic_commands = ['ps']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
@@ -180,7 +200,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -189,7 +209,8 @@ def process(proc_data):
|
||||
"ppid": integer,
|
||||
"c": integer,
|
||||
"stime": string,
|
||||
"tty": string, # ? = Null
|
||||
"tty": string, # ? or ?? = Null
|
||||
"tt": string, # ?? = Null
|
||||
"time": string,
|
||||
"cmd": string,
|
||||
"user": string,
|
||||
@@ -204,6 +225,14 @@ def process(proc_data):
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
# change key name '%cpu' to 'cpu_percent'
|
||||
if '%cpu' in entry:
|
||||
entry['cpu_percent'] = entry.pop('%cpu')
|
||||
|
||||
# change key name '%mem' to 'mem_percent'
|
||||
if '%mem' in entry:
|
||||
entry['mem_percent'] = entry.pop('%mem')
|
||||
|
||||
# change to int
|
||||
int_list = ['pid', 'ppid', 'c', 'vsz', 'rss']
|
||||
for key in int_list:
|
||||
@@ -225,9 +254,13 @@ def process(proc_data):
|
||||
entry[key] = None
|
||||
|
||||
if 'tty' in entry:
|
||||
if entry['tty'] == '?':
|
||||
if entry['tty'] == '?' or entry['tty'] == '??':
|
||||
entry['tty'] = None
|
||||
|
||||
if 'tt' in entry:
|
||||
if entry['tt'] == '??':
|
||||
entry['tt'] = None
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
@@ -243,28 +276,15 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
|
||||
# code adapted from Conor Heine at:
|
||||
# https://gist.github.com/cahna/43a1a3ff4d075bcd71f9d7120037a501
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
cleandata = data.splitlines()
|
||||
headers = [h for h in ' '.join(cleandata[0].lower().strip().split()).split() if h]
|
||||
cleandata[0] = cleandata[0].lower()
|
||||
|
||||
# clean up '%cpu' and '%mem' headers
|
||||
# even though % in a key is valid json, it can make things difficult
|
||||
headers = ['cpu_percent' if x == '%cpu' else x for x in headers]
|
||||
headers = ['mem_percent' if x == '%mem' else x for x in headers]
|
||||
|
||||
raw_data = map(lambda s: s.strip().split(None, len(headers) - 1), cleandata[1:])
|
||||
raw_output = [dict(zip(headers, r)) for r in raw_data]
|
||||
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility route Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --route as the first argument if the piped input is coming from route
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ route -ee | jc --route -p
|
||||
@@ -92,6 +97,21 @@ Examples:
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
import jc.parsers.universal
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'route command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['route']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
@@ -104,7 +124,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -147,22 +167,15 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'aix', 'freebsd']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
|
||||
# code adapted from Conor Heine at:
|
||||
# https://gist.github.com/cahna/43a1a3ff4d075bcd71f9d7120037a501
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
cleandata = data.splitlines()[1:]
|
||||
headers = [h for h in ' '.join(cleandata[0].lower().strip().split()).split() if h]
|
||||
raw_data = map(lambda s: s.strip().split(None, len(headers) - 1), cleandata[1:])
|
||||
raw_output = [dict(zip(headers, r)) for r in raw_data]
|
||||
cleandata[0] = cleandata[0].lower()
|
||||
|
||||
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
"""jc - JSON CLI output utility ss Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ss as the first argument if the piped input is coming from ss
|
||||
|
||||
Limitations:
|
||||
|
||||
Extended information options like -e and -p are not supported and may cause parsing irregularities
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ sudo ss -a | jc --ss -p
|
||||
@@ -244,6 +250,20 @@ import string
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'ss command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['ss']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -254,7 +274,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -315,14 +335,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
contains_colon = ['nl', 'p_raw', 'raw', 'udp', 'tcp', 'v_str', 'icmp6']
|
||||
raw_output = []
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
"""jc - JSON CLI output utility stats Parser
|
||||
"""jc - JSON CLI output utility stat Parser
|
||||
|
||||
Usage:
|
||||
specify --stats as the first argument if the piped input is coming from stats
|
||||
|
||||
specify --stat as the first argument if the piped input is coming from stat
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -98,6 +103,20 @@ Examples:
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'stat command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['stat']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -108,7 +127,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -167,14 +186,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility systemctl Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --systemctl as the first argument if the piped input is coming from systemctl
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ systemctl -a | jc --systemctl -p
|
||||
@@ -34,6 +39,20 @@ Examples:
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'systemctl command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['systemctl']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -44,7 +63,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -72,14 +91,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, systemctlbsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
linedata = data.splitlines()
|
||||
# Clear any blank lines
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility systemctl-lj Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --systemctl-lj as the first argument if the piped input is coming from systemctl list-jobs
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ systemctl list-jobs| jc --systemctl-lj -p
|
||||
@@ -53,6 +58,20 @@ Examples:
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'systemctl list-jobs command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['systemctl list-jobs']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -63,7 +82,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -98,14 +117,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, systemctlbsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
linedata = data.splitlines()
|
||||
# Clear any blank lines
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility systemctl-ls Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --systemctl-ls as the first argument if the piped input is coming from systemctl list-sockets
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ systemctl list-sockets | jc --systemctl-ls -p
|
||||
@@ -28,6 +33,20 @@ Examples:
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'systemctl list-sockets command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['systemctl list-sockets']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -38,7 +57,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -64,14 +83,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, systemctlbsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
linedata = data.splitlines()
|
||||
# Clear any blank lines
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility systemctl-luf Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --systemctl-luf as the first argument if the piped input is coming from systemctl list-unit-files
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ systemctl list-unit-files | jc --systemctl-luf -p
|
||||
@@ -25,6 +30,20 @@ Examples:
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'systemctl list-unit-files command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['systemctl list-unit-files']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -35,7 +54,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -60,14 +79,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, systemctlbsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
linedata = data.splitlines()
|
||||
# Clear any blank lines
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
"""jc - JSON CLI output utility uname Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --uname as the first argument if the piped input is coming from uname
|
||||
|
||||
Limitations:
|
||||
|
||||
must use 'uname -a'
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin'
|
||||
|
||||
Example:
|
||||
|
||||
$ uname -a | jc --uname -p
|
||||
@@ -23,6 +29,20 @@ Example:
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'uname -a command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin']
|
||||
magic_commands = ['uname']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -33,7 +53,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
Dictionary. Structured data with the following schema:
|
||||
|
||||
{
|
||||
"kernel_name": string,
|
||||
@@ -62,32 +82,39 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
Dictionary. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = {}
|
||||
parsed_line = data.split(maxsplit=3)
|
||||
split_line = data.split()
|
||||
|
||||
if len(parsed_line) > 1:
|
||||
if len(split_line) > 1:
|
||||
# check for OSX output
|
||||
if data.startswith('Darwin'):
|
||||
parsed_line = data.split()
|
||||
raw_output['machine'] = parsed_line.pop(-1)
|
||||
raw_output['kernel_name'] = parsed_line.pop(0)
|
||||
raw_output['node_name'] = parsed_line.pop(0)
|
||||
raw_output['kernel_release'] = parsed_line.pop(0)
|
||||
raw_output['kernel_version'] = ' '.join(parsed_line)
|
||||
|
||||
raw_output['kernel_name'] = parsed_line.pop(0)
|
||||
raw_output['node_name'] = parsed_line.pop(0)
|
||||
raw_output['kernel_release'] = parsed_line.pop(0)
|
||||
# otherwise use linux parser
|
||||
else:
|
||||
parsed_line = data.split(maxsplit=3)
|
||||
raw_output['kernel_name'] = parsed_line.pop(0)
|
||||
raw_output['node_name'] = parsed_line.pop(0)
|
||||
raw_output['kernel_release'] = parsed_line.pop(0)
|
||||
|
||||
parsed_line = parsed_line[-1].rsplit(maxsplit=4)
|
||||
parsed_line = parsed_line[-1].rsplit(maxsplit=4)
|
||||
|
||||
raw_output['operating_system'] = parsed_line.pop(-1)
|
||||
raw_output['hardware_platform'] = parsed_line.pop(-1)
|
||||
raw_output['processor'] = parsed_line.pop(-1)
|
||||
raw_output['machine'] = parsed_line.pop(-1)
|
||||
raw_output['operating_system'] = parsed_line.pop(-1)
|
||||
raw_output['hardware_platform'] = parsed_line.pop(-1)
|
||||
raw_output['processor'] = parsed_line.pop(-1)
|
||||
raw_output['machine'] = parsed_line.pop(-1)
|
||||
|
||||
raw_output['kernel_version'] = parsed_line.pop(0)
|
||||
raw_output['kernel_version'] = parsed_line.pop(0)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
|
||||
110
jc/parsers/universal.py
Normal file
110
jc/parsers/universal.py
Normal file
@@ -0,0 +1,110 @@
|
||||
"""jc - JSON CLI output utility universal Parsers"""
|
||||
|
||||
|
||||
import string
|
||||
|
||||
|
||||
def simple_table_parse(data):
|
||||
"""
|
||||
Parse simple tables. The last column may contain data with spaces
|
||||
|
||||
code adapted from Conor Heine at:
|
||||
https://gist.github.com/cahna/43a1a3ff4d075bcd71f9d7120037a501
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (list) Text data to parse that has been split into lines via .splitlines().
|
||||
Item 0 must be the header row. Any spaces in header names should be
|
||||
changed to underscore '_'. You should also ensure headers are
|
||||
lowercase by using .lower().
|
||||
|
||||
Also, ensure there are no blank lines (list items) in the data.
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw structured data
|
||||
"""
|
||||
headers = [h for h in ' '.join(data[0].strip().split()).split() if h]
|
||||
raw_data = map(lambda s: s.strip().split(None, len(headers) - 1), data[1:])
|
||||
raw_output = [dict(zip(headers, r)) for r in raw_data]
|
||||
|
||||
return raw_output
|
||||
|
||||
|
||||
def sparse_table_parse(data, delim='\u2063'):
|
||||
"""
|
||||
Parse tables with missing column data or with spaces in column data.
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (list) Text data to parse that has been split into lines via .splitlines().
|
||||
Item 0 must be the header row. Any spaces in header names should be
|
||||
changed to underscore '_'. You should also ensure headers are
|
||||
lowercase by using .lower(). Do not change the position of header
|
||||
names as the positions are used to find the data.
|
||||
|
||||
Also, ensure there are no blank lines (list items) in the data.
|
||||
|
||||
delim: (string) Delimiter to use. By default 'u\2063' (invisible separator) is used
|
||||
since this is unlikely to ever be seen in terminal output. You can
|
||||
change this for troubleshooting purposes or if there is a delimiter
|
||||
conflict with your data.
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw structured data
|
||||
"""
|
||||
output = []
|
||||
header_text = data.pop(0)
|
||||
header_text = header_text + ' '
|
||||
header_list = header_text.split()
|
||||
|
||||
# find each column index and end position
|
||||
header_search = [header_list[0]]
|
||||
for h in header_list[1:]:
|
||||
header_search.append(' ' + h + ' ')
|
||||
|
||||
header_spec_list = []
|
||||
for i, column in enumerate(header_list[0:len(header_list) - 1]):
|
||||
header_spec = {
|
||||
'name': column,
|
||||
'end': header_text.find(header_search[i + 1])
|
||||
}
|
||||
|
||||
header_spec_list.append(header_spec)
|
||||
|
||||
# parse lines
|
||||
if data:
|
||||
for entry in data:
|
||||
output_line = {}
|
||||
|
||||
# insert new separator since data can contain spaces
|
||||
for col in reversed(header_list):
|
||||
# find the right header_spec
|
||||
for h_spec in header_spec_list:
|
||||
if h_spec['name'] == col:
|
||||
h_end = h_spec['end']
|
||||
# check if the location contains whitespace. if not
|
||||
# then move to the left until a space is found
|
||||
while h_end > 0 and entry[h_end] not in string.whitespace:
|
||||
h_end -= 1
|
||||
|
||||
# insert custom delimiter
|
||||
entry = entry[:h_end] + delim + entry[h_end + 1:]
|
||||
|
||||
# create the entry list from the new custom delimiter
|
||||
entry_list = entry.split(delim, maxsplit=len(header_list) - 1)
|
||||
|
||||
# clean up leading and trailing spaces in entry
|
||||
clean_entry_list = []
|
||||
for col in entry_list:
|
||||
clean_entry = col.strip()
|
||||
if clean_entry == '':
|
||||
clean_entry = None
|
||||
|
||||
clean_entry_list.append(clean_entry)
|
||||
|
||||
output_line = dict(zip(header_list, clean_entry_list))
|
||||
output.append(output_line)
|
||||
|
||||
return output
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility uptime Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --uptime as the first argument if the piped input is coming from uptime
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Example:
|
||||
|
||||
$ uptime | jc --uptime -p
|
||||
@@ -28,6 +33,20 @@ Example:
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'uptime command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
magic_commands = ['uptime']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -38,7 +57,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
Dictionary. Structured data with the following schema:
|
||||
|
||||
{
|
||||
"time": string,
|
||||
@@ -82,14 +101,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
Dictionary. Raw or processed structured data
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = {}
|
||||
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""jc - JSON CLI output utility w Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --w as the first argument if the piped input is coming from w
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ w | jc --w -p
|
||||
@@ -77,6 +82,20 @@ import string
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'w command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
magic_commands = ['w']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
@@ -87,7 +106,7 @@ def process(proc_data):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary structured data with the following schema:
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
@@ -124,14 +143,10 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Returns:
|
||||
|
||||
dictionary raw or processed structured data
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
cleandata = data.splitlines()[1:]
|
||||
header_text = cleandata[0].lower()
|
||||
|
||||
120
jc/parsers/xml.py
Normal file
120
jc/parsers/xml.py
Normal file
@@ -0,0 +1,120 @@
|
||||
"""jc - JSON CLI output utility XML Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --xml as the first argument if the piped input is coming from an XML file
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat cd_catalog.xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CATALOG>
|
||||
<CD>
|
||||
<TITLE>Empire Burlesque</TITLE>
|
||||
<ARTIST>Bob Dylan</ARTIST>
|
||||
<COUNTRY>USA</COUNTRY>
|
||||
<COMPANY>Columbia</COMPANY>
|
||||
<PRICE>10.90</PRICE>
|
||||
<YEAR>1985</YEAR>
|
||||
</CD>
|
||||
<CD>
|
||||
<TITLE>Hide your heart</TITLE>
|
||||
<ARTIST>Bonnie Tyler</ARTIST>
|
||||
<COUNTRY>UK</COUNTRY>
|
||||
<COMPANY>CBS Records</COMPANY>
|
||||
<PRICE>9.90</PRICE>
|
||||
<YEAR>1988</YEAR>
|
||||
</CD>
|
||||
...
|
||||
|
||||
$ cat cd_catalog.xml | jc --xml -p
|
||||
{
|
||||
"CATALOG": {
|
||||
"CD": [
|
||||
{
|
||||
"TITLE": "Empire Burlesque",
|
||||
"ARTIST": "Bob Dylan",
|
||||
"COUNTRY": "USA",
|
||||
"COMPANY": "Columbia",
|
||||
"PRICE": "10.90",
|
||||
"YEAR": "1985"
|
||||
},
|
||||
{
|
||||
"TITLE": "Hide your heart",
|
||||
"ARTIST": "Bonnie Tyler",
|
||||
"COUNTRY": "UK",
|
||||
"COMPANY": "CBS Records",
|
||||
"PRICE": "9.90",
|
||||
"YEAR": "1988"
|
||||
},
|
||||
...
|
||||
}
|
||||
"""
|
||||
import jc.utils
|
||||
import xmltodict
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'XML file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
details = 'Using the xmltodict library at https://github.com/martinblech/xmltodict'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary representing an XML document:
|
||||
|
||||
{
|
||||
XML Document converted to a Dictionary
|
||||
See https://github.com/martinblech/xmltodict for details
|
||||
}
|
||||
"""
|
||||
|
||||
# No further processing
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
if data:
|
||||
raw_output = xmltodict.parse(data)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
137
jc/parsers/yaml.py
Normal file
137
jc/parsers/yaml.py
Normal file
@@ -0,0 +1,137 @@
|
||||
"""jc - JSON CLI output utility YAML Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --yaml as the first argument if the piped input is coming from a YAML file
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat istio-mtls-permissive.yaml
|
||||
apiVersion: "authentication.istio.io/v1alpha1"
|
||||
kind: "Policy"
|
||||
metadata:
|
||||
name: "default"
|
||||
namespace: "default"
|
||||
spec:
|
||||
peers:
|
||||
- mtls: {}
|
||||
---
|
||||
apiVersion: "networking.istio.io/v1alpha3"
|
||||
kind: "DestinationRule"
|
||||
metadata:
|
||||
name: "default"
|
||||
namespace: "default"
|
||||
spec:
|
||||
host: "*.default.svc.cluster.local"
|
||||
trafficPolicy:
|
||||
tls:
|
||||
mode: ISTIO_MUTUAL
|
||||
|
||||
$ cat istio-mtls-permissive.yaml | jc --yaml -p
|
||||
[
|
||||
{
|
||||
"apiVersion": "authentication.istio.io/v1alpha1",
|
||||
"kind": "Policy",
|
||||
"metadata": {
|
||||
"name": "default",
|
||||
"namespace": "default"
|
||||
},
|
||||
"spec": {
|
||||
"peers": [
|
||||
{
|
||||
"mtls": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "networking.istio.io/v1alpha3",
|
||||
"kind": "DestinationRule",
|
||||
"metadata": {
|
||||
"name": "default",
|
||||
"namespace": "default"
|
||||
},
|
||||
"spec": {
|
||||
"host": "*.default.svc.cluster.local",
|
||||
"trafficPolicy": {
|
||||
"tls": {
|
||||
"mode": "ISTIO_MUTUAL"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
from ruamel.yaml import YAML
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'YAML file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
details = 'Using the ruamel.yaml library at https://pypi.org/project/ruamel.yaml'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Each dictionary represents a YAML document:
|
||||
|
||||
[
|
||||
{
|
||||
YAML Document converted to a Dictionary
|
||||
See https://pypi.org/project/ruamel.yaml for details
|
||||
}
|
||||
]
|
||||
"""
|
||||
|
||||
# No further processing
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
yaml = YAML(typ='safe')
|
||||
|
||||
for document in yaml.load_all(data):
|
||||
raw_output.append(document)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
@@ -34,7 +34,7 @@ def error_message(message):
|
||||
|
||||
no return, just prints output to STDERR
|
||||
"""
|
||||
|
||||
|
||||
error_string = f'''
|
||||
jc: Error - {message}
|
||||
'''
|
||||
@@ -43,13 +43,13 @@ def error_message(message):
|
||||
|
||||
def compatibility(mod_name, compatible):
|
||||
"""Checks for the parser's compatibility with the running OS platform.
|
||||
|
||||
|
||||
Parameters:
|
||||
|
||||
mod_name: (string) __name__ of the calling module
|
||||
|
||||
|
||||
compatible: (list) sys.platform name(s) compatible with the parser
|
||||
compatible options:
|
||||
compatible options:
|
||||
linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Returns:
|
||||
|
||||
11
setup.py
11
setup.py
@@ -5,19 +5,22 @@ with open('README.md', 'r') as f:
|
||||
|
||||
setuptools.setup(
|
||||
name='jc',
|
||||
version='1.5.1',
|
||||
version='1.7.4',
|
||||
author='Kelly Brazil',
|
||||
author_email='kellyjonbrazil@gmail.com',
|
||||
description='This tool serializes the output of popular command line tools to structured JSON output.',
|
||||
description='This tool serializes the output of popular command line tools and filetypes to structured JSON output.',
|
||||
install_requires=[
|
||||
'ifconfig-parser'
|
||||
'ifconfig-parser>=0.0.5',
|
||||
'ruamel.yaml>=0.15.0',
|
||||
'xmltodict>=0.12.0'
|
||||
],
|
||||
license='MIT',
|
||||
long_description=long_description,
|
||||
long_description_content_type='text/markdown',
|
||||
python_requires='~=3.6',
|
||||
python_requires='>=3.6',
|
||||
url='https://github.com/kellyjonbrazil/jc',
|
||||
packages=setuptools.find_packages(),
|
||||
include_package_data=True,
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
'jc=jc.cli:main'
|
||||
|
||||
1
tests/fixtures/centos-7.7/crontab-u.json
vendored
Normal file
1
tests/fixtures/centos-7.7/crontab-u.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"variables": [{"name": "MAILTO", "value": "root"}, {"name": "PATH", "value": "/sbin:/bin:/usr/sbin:/usr/bin"}, {"name": "SHELL", "value": "/bin/bash"}], "schedule": [{"minute": ["01"], "hour": ["*"], "day_of_month": ["*"], "month": ["*"], "day_of_week": ["*"], "user": "root", "command": "run-parts /etc/cron.hourly"}, {"occurrence": "hourly", "user": "root", "command": "/usr/local/bin/backup"}]}
|
||||
6
tests/fixtures/centos-7.7/crontab-u.out
vendored
Normal file
6
tests/fixtures/centos-7.7/crontab-u.out
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
# Run the hourly jobs
|
||||
SHELL=/bin/bash
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
MAILTO=root
|
||||
@hourly root /usr/local/bin/backup
|
||||
01 * * * * root run-parts /etc/cron.hourly
|
||||
1
tests/fixtures/centos-7.7/crontab.json
vendored
Normal file
1
tests/fixtures/centos-7.7/crontab.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"variables": [{"name": "MAILTO", "value": "root"}, {"name": "PATH", "value": "/sbin:/bin:/usr/sbin:/usr/bin"}, {"name": "SHELL", "value": "/bin/bash"}], "schedule": [{"minute": ["0"], "hour": ["*"], "day_of_month": ["*"], "month": ["*"], "day_of_week": ["*"], "command": "/usr/bin/wget -O - -q -t 1 http://localhost/cron.php"}, {"minute": ["*"], "hour": ["*"], "day_of_month": ["*"], "month": ["*"], "day_of_week": ["*"], "command": "/var/www/devdaily.com/bin/check-apache.sh"}, {"minute": ["5"], "hour": ["10-11", "22"], "day_of_month": ["*"], "month": ["*"], "day_of_week": ["*"], "command": "/var/www/devdaily.com/bin/mk-new-links.php"}, {"minute": ["30"], "hour": ["4/2"], "day_of_month": ["*"], "month": ["*"], "day_of_week": ["*"], "command": "/var/www/devdaily.com/bin/create-all-backups.sh"}, {"minute": ["5"], "hour": ["0", "4", "10", "16"], "day_of_month": ["*"], "month": ["*"], "day_of_week": ["*"], "command": "/var/www/devdaily.com/bin/create-cat-list.sh"}, {"minute": ["5"], "hour": ["0"], "day_of_month": ["*"], "month": ["*"], "day_of_week": ["*"], "command": "/var/www/devdaily.com/bin/resetContactForm.sh"}, {"minute": ["0", "20", "40"], "hour": ["*"], "day_of_month": ["*"], "month": ["*"], "day_of_week": ["*"], "command": "/var/www/bin/ads/freshMint.sh"}, {"minute": ["5", "25", "45"], "hour": ["*"], "day_of_month": ["*"], "month": ["*"], "day_of_week": ["*"], "command": "/var/www/bin/ads/greenTaffy.sh"}, {"minute": ["10", "30", "50"], "hour": ["*"], "day_of_month": ["*"], "month": ["*"], "day_of_week": ["*"], "command": "/var/www/bin/ads/raspberry.sh"}, {"minute": ["15", "35", "55"], "hour": ["*"], "day_of_month": ["*"], "month": ["*"], "day_of_week": ["*"], "command": "/var/www/bin/ads/robinsEgg.sh"}, {"occurrence": "yearly", "command": "/home/maverick/bin/annual-maintenance"}, {"occurrence": "reboot", "command": "/home/cleanup"}, {"occurrence": "monthly", "command": "/home/maverick/bin/tape-backup"}]}
|
||||
48
tests/fixtures/centos-7.7/crontab.out
vendored
Normal file
48
tests/fixtures/centos-7.7/crontab.out
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
SHELL=/bin/bash
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
MAILTO=root
|
||||
|
||||
#--------------------------------------------------
|
||||
# example unix/linux crontab file format:
|
||||
#--------------------------------------------------
|
||||
# min,hour,dayOfMonth,month,dayOfWeek command
|
||||
#
|
||||
# field allowed values
|
||||
# ----- --------------
|
||||
# minute 0-59
|
||||
# hour 0-23
|
||||
# day of month 1-31
|
||||
# month 1-12 (or names, see below)
|
||||
# day of week 0-7 (0 or 7 is Sun, or use names)
|
||||
#
|
||||
#--------------------------------------------------
|
||||
|
||||
# run the drupal cron process every hour of every day
|
||||
0 * * * * /usr/bin/wget -O - -q -t 1 http://localhost/cron.php
|
||||
|
||||
# run this apache kludge every minute of every day
|
||||
* * * * * /var/www/devdaily.com/bin/check-apache.sh
|
||||
|
||||
# generate links to new blog posts twice a day
|
||||
5 10-11,22 * * * /var/www/devdaily.com/bin/mk-new-links.php
|
||||
|
||||
# run the backup scripts at 4:30am
|
||||
30 4/2 * * * /var/www/devdaily.com/bin/create-all-backups.sh
|
||||
|
||||
# re-generate the blog "categories" list (four times a day)
|
||||
5 0,4,10,16 * * * /var/www/devdaily.com/bin/create-cat-list.sh
|
||||
|
||||
# reset the contact form just after midnight
|
||||
5 0 * * * /var/www/devdaily.com/bin/resetContactForm.sh
|
||||
|
||||
# example of shortcut versions
|
||||
@monthly /home/maverick/bin/tape-backup
|
||||
@reboot /home/cleanup
|
||||
@yearly /home/maverick/bin/annual-maintenance
|
||||
|
||||
# rotate the ad banners every five minutes
|
||||
|
||||
0,20,40 * * * * /var/www/bin/ads/freshMint.sh
|
||||
5,25,45 * * * * /var/www/bin/ads/greenTaffy.sh
|
||||
10,30,50 * * * * /var/www/bin/ads/raspberry.sh
|
||||
15,35,55 * * * * /var/www/bin/ads/robinsEgg.sh
|
||||
2
tests/fixtures/centos-7.7/df.json
vendored
2
tests/fixtures/centos-7.7/df.json
vendored
@@ -1 +1 @@
|
||||
[{"filesystem": "devtmpfs", "1k-blocks": 1918816, "used": 0, "available": 1918816, "use_percent": 0, "mounted_on": "/dev"}, {"filesystem": "tmpfs", "1k-blocks": 1930664, "used": 0, "available": 1930664, "use_percent": 0, "mounted_on": "/dev/shm"}, {"filesystem": "tmpfs", "1k-blocks": 1930664, "used": 11832, "available": 1918832, "use_percent": 1, "mounted_on": "/run"}, {"filesystem": "tmpfs", "1k-blocks": 1930664, "used": 0, "available": 1930664, "use_percent": 0, "mounted_on": "/sys/fs/cgroup"}, {"filesystem": "/dev/mapper/centos-root", "1k-blocks": 17811456, "used": 1805580, "available": 16005876, "use_percent": 11, "mounted_on": "/"}, {"filesystem": "/dev/sda1", "1k-blocks": 1038336, "used": 237600, "available": 800736, "use_percent": 23, "mounted_on": "/boot"}, {"filesystem": "tmpfs", "1k-blocks": 386136, "used": 0, "available": 386136, "use_percent": 0, "mounted_on": "/run/user/1000"}]
|
||||
[{"filesystem": "devtmpfs", "1k_blocks": 1918816, "used": 0, "available": 1918816, "use_percent": 0, "mounted_on": "/dev"}, {"filesystem": "tmpfs", "1k_blocks": 1930664, "used": 0, "available": 1930664, "use_percent": 0, "mounted_on": "/dev/shm"}, {"filesystem": "tmpfs", "1k_blocks": 1930664, "used": 11832, "available": 1918832, "use_percent": 1, "mounted_on": "/run"}, {"filesystem": "tmpfs", "1k_blocks": 1930664, "used": 0, "available": 1930664, "use_percent": 0, "mounted_on": "/sys/fs/cgroup"}, {"filesystem": "/dev/mapper/centos-root", "1k_blocks": 17811456, "used": 1805580, "available": 16005876, "use_percent": 11, "mounted_on": "/"}, {"filesystem": "/dev/sda1", "1k_blocks": 1038336, "used": 237600, "available": 800736, "use_percent": 23, "mounted_on": "/boot"}, {"filesystem": "tmpfs", "1k_blocks": 386136, "used": 0, "available": 386136, "use_percent": 0, "mounted_on": "/run/user/1000"}]
|
||||
|
||||
1
tests/fixtures/centos-7.7/du.json
vendored
Normal file
1
tests/fixtures/centos-7.7/du.json
vendored
Normal file
File diff suppressed because one or more lines are too long
5199
tests/fixtures/centos-7.7/du.out
vendored
Normal file
5199
tests/fixtures/centos-7.7/du.out
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2
tests/fixtures/centos-7.7/history.json
vendored
2
tests/fixtures/centos-7.7/history.json
vendored
File diff suppressed because one or more lines are too long
1
tests/fixtures/centos-7.7/id.json
vendored
Normal file
1
tests/fixtures/centos-7.7/id.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"uid": {"id": 1000, "name": "kbrazil"}, "gid": {"id": 1000, "name": "kbrazil"}, "groups": [{"id": 1000, "name": "kbrazil"}, {"id": 10, "name": "wheel"}], "context": {"user": "unconfined_u", "role": "unconfined_r", "type": "unconfined_t", "level": "s0-s0:c0.c1023"}}
|
||||
1
tests/fixtures/centos-7.7/id.out
vendored
Normal file
1
tests/fixtures/centos-7.7/id.out
vendored
Normal file
@@ -0,0 +1 @@
|
||||
uid=1000(kbrazil) gid=1000(kbrazil) groups=1000(kbrazil),10(wheel) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
|
||||
2
tests/fixtures/centos-7.7/ifconfig.json
vendored
2
tests/fixtures/centos-7.7/ifconfig.json
vendored
@@ -1 +1 @@
|
||||
[{"name": "docker0", "flags": 4099, "state": "UP,BROADCAST,MULTICAST", "mtu": 1500, "ipv4_addr": "172.17.0.1", "ipv4_mask": "255.255.0.0", "ipv4_bcast": "0.0.0.0", "mac_addr": "02:42:b1:9a:ea:02", "type": "Ethernet", "rx_packets": 0, "rx_errors": 0, "rx_dropped": 0, "rx_overruns": 0, "rx_frame": 0, "tx_packets": 0, "tx_errors": 0, "tx_dropped": 0, "tx_overruns": 0, "tx_carrier": 0, "tx_collisions": 0, "ipv6_addr": null, "ipv6_mask": null, "ipv6_scope": null, "metric": null}, {"name": "ens33", "flags": 4163, "state": "UP,BROADCAST,RUNNING,MULTICAST", "mtu": 1500, "ipv4_addr": "192.168.71.137", "ipv4_mask": "255.255.255.0", "ipv4_bcast": "192.168.71.255", "ipv6_addr": "fe80::c1cb:715d:bc3e:b8a0", "ipv6_mask": 64, "ipv6_scope": "link", "mac_addr": "00:0c:29:3b:58:0e", "type": "Ethernet", "rx_packets": 8061, "rx_errors": 0, "rx_dropped": 0, "rx_overruns": 0, "rx_frame": 0, "tx_packets": 4502, "tx_errors": 0, "tx_dropped": 0, "tx_overruns": 0, "tx_carrier": 0, "tx_collisions": 0, "metric": null}, {"name": "lo", "flags": 73, "state": "UP,LOOPBACK,RUNNING", "mtu": 65536, "ipv4_addr": "127.0.0.1", "ipv4_mask": "255.0.0.0", "ipv4_bcast": null, "ipv6_addr": "::1", "ipv6_mask": 128, "ipv6_scope": "host", "mac_addr": null, "type": "Local Loopback", "rx_packets": 73, "rx_errors": 0, "rx_dropped": 0, "rx_overruns": 0, "rx_frame": 0, "tx_packets": 73, "tx_errors": 0, "tx_dropped": 0, "tx_overruns": 0, "tx_carrier": 0, "tx_collisions": 0, "metric": null}]
|
||||
[{"name": "docker0", "flags": 4099, "state": ["UP", "BROADCAST", "MULTICAST"], "mtu": 1500, "ipv4_addr": "172.17.0.1", "ipv4_mask": "255.255.0.0", "ipv4_bcast": "0.0.0.0", "mac_addr": "02:42:b1:9a:ea:02", "type": "Ethernet", "rx_packets": 0, "rx_bytes": 0, "rx_errors": 0, "rx_dropped": 0, "rx_overruns": 0, "rx_frame": 0, "tx_packets": 0, "tx_bytes": 0, "tx_errors": 0, "tx_dropped": 0, "tx_overruns": 0, "tx_carrier": 0, "tx_collisions": 0, "ipv6_addr": null, "ipv6_mask": null, "ipv6_scope": null, "metric": null}, {"name": "ens33", "flags": 4163, "state": ["UP", "BROADCAST", "RUNNING", "MULTICAST"], "mtu": 1500, "ipv4_addr": "192.168.71.137", "ipv4_mask": "255.255.255.0", "ipv4_bcast": "192.168.71.255", "ipv6_addr": "fe80::c1cb:715d:bc3e:b8a0", "ipv6_mask": 64, "ipv6_scope": "0x20", "mac_addr": "00:0c:29:3b:58:0e", "type": "Ethernet", "rx_packets": 8061, "rx_bytes": 1514413, "rx_errors": 0, "rx_dropped": 0, "rx_overruns": 0, "rx_frame": 0, "tx_packets": 4502, "tx_bytes": 866622, "tx_errors": 0, "tx_dropped": 0, "tx_overruns": 0, "tx_carrier": 0, "tx_collisions": 0, "metric": null}, {"name": "lo", "flags": 73, "state": ["UP", "LOOPBACK", "RUNNING"], "mtu": 65536, "ipv4_addr": "127.0.0.1", "ipv4_mask": "255.0.0.0", "ipv4_bcast": null, "ipv6_addr": "::1", "ipv6_mask": 128, "ipv6_scope": "0x10", "mac_addr": null, "type": "Local Loopback", "rx_packets": 73, "rx_bytes": 6009, "rx_errors": 0, "rx_dropped": 0, "rx_overruns": 0, "rx_frame": 0, "tx_packets": 73, "tx_bytes": 6009, "tx_errors": 0, "tx_dropped": 0, "tx_overruns": 0, "tx_carrier": 0, "tx_collisions": 0, "metric": null}]
|
||||
|
||||
1
tests/fixtures/centos-7.7/ls-R.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-R.json
vendored
Normal file
File diff suppressed because one or more lines are too long
5089
tests/fixtures/centos-7.7/ls-R.out
vendored
Normal file
5089
tests/fixtures/centos-7.7/ls-R.out
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
tests/fixtures/centos-7.7/ls-alR.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-alR.json
vendored
Normal file
File diff suppressed because one or more lines are too long
4997
tests/fixtures/centos-7.7/ls-alR.out
vendored
Normal file
4997
tests/fixtures/centos-7.7/ls-alR.out
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
tests/fixtures/centos-7.7/ls-glob.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-glob.json
vendored
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user