mirror of
https://github.com/kellyjonbrazil/jc.git
synced 2026-04-03 17:44:07 +02:00
Compare commits
351 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d753e71a74 | ||
|
|
2e4f5a508b | ||
|
|
88b960eff6 | ||
|
|
88c77bd89e | ||
|
|
51a7a4251f | ||
|
|
51d2f316f3 | ||
|
|
ff78a46c48 | ||
|
|
ed4a9dc1d4 | ||
|
|
63182dba26 | ||
|
|
9c1eaa9389 | ||
|
|
bc520fcbcd | ||
|
|
46faac1a12 | ||
|
|
3c424c0cb3 | ||
|
|
3ac8d0362b | ||
|
|
d88b998e6c | ||
|
|
a9ed55c006 | ||
|
|
ea61434123 | ||
|
|
a73d0d26cb | ||
|
|
b4506976e3 | ||
|
|
34cb75a096 | ||
|
|
34df643f60 | ||
|
|
ac7c13fcc0 | ||
|
|
4fdb34c7d5 | ||
|
|
7ac468e35a | ||
|
|
df190aa299 | ||
|
|
9621475e86 | ||
|
|
82e0160de8 | ||
|
|
d03fb8b626 | ||
|
|
b300dfb3d7 | ||
|
|
a7de9111d9 | ||
|
|
7933dfdbe7 | ||
|
|
f7cb5f7d01 | ||
|
|
a26a298f1a | ||
|
|
dbd134d0da | ||
|
|
11aa01b0d9 | ||
|
|
6f18e53443 | ||
|
|
7b467c4665 | ||
|
|
537b8f2630 | ||
|
|
4d823575e7 | ||
|
|
541aa1d09f | ||
|
|
8f02021014 | ||
|
|
158a15157c | ||
|
|
2752e0d66a | ||
|
|
6c11e912af | ||
|
|
43d34461e2 | ||
|
|
4dfdc9b0f6 | ||
|
|
e2311cbb03 | ||
|
|
bf15575e90 | ||
|
|
406336c718 | ||
|
|
6665ffaeb8 | ||
|
|
dcf552ca0c | ||
|
|
7a6ebf3c95 | ||
|
|
d2dc4a983c | ||
|
|
1168259bc2 | ||
|
|
e8e4b46021 | ||
|
|
12d2de2282 | ||
|
|
0e2fe401e1 | ||
|
|
14247adb0a | ||
|
|
3a9f0934c4 | ||
|
|
caf0a5c871 | ||
|
|
cfb58b1cf3 | ||
|
|
975cf195cc | ||
|
|
8a46a259a3 | ||
|
|
e395142e59 | ||
|
|
caaeaf0d67 | ||
|
|
21e69a7cbf | ||
|
|
603964935b | ||
|
|
47eb83ae55 | ||
|
|
fc0ce6c959 | ||
|
|
077a29fb4e | ||
|
|
8568d0d328 | ||
|
|
597d39c28e | ||
|
|
eb888dcbbc | ||
|
|
d1b9ac0841 | ||
|
|
89a6d9c5c3 | ||
|
|
85d9837616 | ||
|
|
cd7731484d | ||
|
|
086da16b17 | ||
|
|
20830528f0 | ||
|
|
83371edd8f | ||
|
|
364a81decc | ||
|
|
ef09592ad3 | ||
|
|
4a86e109cc | ||
|
|
7fa5391b66 | ||
|
|
9b53ba5714 | ||
|
|
b59e38cfd2 | ||
|
|
5ba22dae59 | ||
|
|
4232e523ac | ||
|
|
bee80b35d2 | ||
|
|
c32395f695 | ||
|
|
735c5e1078 | ||
|
|
d09c94b292 | ||
|
|
4d04866f48 | ||
|
|
a2d90f4dfc | ||
|
|
93a5002c8b | ||
|
|
23bf5227a4 | ||
|
|
77c96fa2a9 | ||
|
|
3f5a1f015e | ||
|
|
b280c4fc18 | ||
|
|
3ab9b43a2e | ||
|
|
46f568414a | ||
|
|
cba2fd299f | ||
|
|
1e6e44f656 | ||
|
|
acac039994 | ||
|
|
50a3b34016 | ||
|
|
b45396070c | ||
|
|
218b9aec8a | ||
|
|
2b887debc6 | ||
|
|
0313e3f8ca | ||
|
|
1669e6e20c | ||
|
|
ef6de75dda | ||
|
|
a6bcec425a | ||
|
|
596ad9a64d | ||
|
|
7a91c93319 | ||
|
|
b5f7b35f89 | ||
|
|
2f47fb7f14 | ||
|
|
1b214c4036 | ||
|
|
8f94f8acc6 | ||
|
|
3a2a69cfa5 | ||
|
|
f599c65988 | ||
|
|
ad12849fd9 | ||
|
|
f36b3789e8 | ||
|
|
6d18c0ba61 | ||
|
|
17097abec9 | ||
|
|
b7ddd3b285 | ||
|
|
75b23f62c9 | ||
|
|
f88967b2a5 | ||
|
|
ba2846664b | ||
|
|
10dba37ca2 | ||
|
|
0e6f938514 | ||
|
|
159d87c112 | ||
|
|
9e7b1621cf | ||
|
|
2057817ef8 | ||
|
|
a1eabad2d3 | ||
|
|
92bf2b1ca2 | ||
|
|
2b2123a4ba | ||
|
|
908b2f9200 | ||
|
|
deff0c7bfd | ||
|
|
7cd01efa64 | ||
|
|
2dbe56456b | ||
|
|
6078a411ef | ||
|
|
4a3656562f | ||
|
|
ba75989a24 | ||
|
|
9e9e2c3628 | ||
|
|
9a2a8c6b61 | ||
|
|
dae42ef161 | ||
|
|
931f2cab78 | ||
|
|
72b061bed4 | ||
|
|
29a7c73990 | ||
|
|
2d1d68e300 | ||
|
|
c5c1e170d1 | ||
|
|
9c1bb66452 | ||
|
|
a4f3306bae | ||
|
|
1bc638b6ee | ||
|
|
9ad0cd9dae | ||
|
|
6d4a469127 | ||
|
|
ed6997e3ff | ||
|
|
eb788fca6e | ||
|
|
9186f5f377 | ||
|
|
30cff5f281 | ||
|
|
b724e0969a | ||
|
|
a62c49e871 | ||
|
|
9b160f6279 | ||
|
|
338a4e2612 | ||
|
|
0140688750 | ||
|
|
73e5ea98c1 | ||
|
|
77dcbc544d | ||
|
|
c7bcb0947a | ||
|
|
5cd3f7f71d | ||
|
|
5044388ab2 | ||
|
|
ee075db598 | ||
|
|
9904e0be61 | ||
|
|
31b69b3242 | ||
|
|
e6a80fea32 | ||
|
|
d6aec00e03 | ||
|
|
4aa7d81e11 | ||
|
|
48cdabc3b0 | ||
|
|
a1791ef547 | ||
|
|
7bc87f6c2d | ||
|
|
bbed9e274b | ||
|
|
486282b985 | ||
|
|
a4d45b653f | ||
|
|
22e151b01c | ||
|
|
7a4ebcd1ec | ||
|
|
651cbfe02f | ||
|
|
8c3e764516 | ||
|
|
b4e75da7e3 | ||
|
|
37223f086c | ||
|
|
a404033735 | ||
|
|
b7433ed085 | ||
|
|
224d3d65ad | ||
|
|
a349fb0bda | ||
|
|
e7ddcfb83f | ||
|
|
abd20dfe36 | ||
|
|
dc1fd3ef1b | ||
|
|
98a7686db4 | ||
|
|
9c6c6c4330 | ||
|
|
f9be5651da | ||
|
|
df9835a3e6 | ||
|
|
92363be2dd | ||
|
|
31b6203015 | ||
|
|
18805858d6 | ||
|
|
e676f0e20f | ||
|
|
20652edefa | ||
|
|
98c29d0747 | ||
|
|
41a6311f6b | ||
|
|
978760ec57 | ||
|
|
d410425537 | ||
|
|
6b7430329c | ||
|
|
40fe0d4a60 | ||
|
|
365c5354a0 | ||
|
|
b246a05cbb | ||
|
|
9e5a7a4abb | ||
|
|
f266acbcca | ||
|
|
4e3b471f18 | ||
|
|
5e28736c2e | ||
|
|
a91913a3b5 | ||
|
|
90c64f0ae0 | ||
|
|
7cc642ed1a | ||
|
|
809f64d35a | ||
|
|
a6f859a55e | ||
|
|
39ef88078f | ||
|
|
aeea5e8d2e | ||
|
|
1a0700bff4 | ||
|
|
b5fa6d068f | ||
|
|
1baec0b420 | ||
|
|
4f2a4e1dee | ||
|
|
758d617668 | ||
|
|
55322c37f5 | ||
|
|
d19ea5552b | ||
|
|
130c3527c1 | ||
|
|
3f221f4714 | ||
|
|
d64c4cb390 | ||
|
|
448c56aa46 | ||
|
|
9fbea15b6d | ||
|
|
932060314b | ||
|
|
5e68ae5009 | ||
|
|
d03541beae | ||
|
|
516fa571d9 | ||
|
|
a19c12096a | ||
|
|
758f27945d | ||
|
|
8b1e8d58df | ||
|
|
b967489d08 | ||
|
|
870d0218be | ||
|
|
84020bc2af | ||
|
|
4efe5344e0 | ||
|
|
9182c54513 | ||
|
|
28f0ab0b02 | ||
|
|
90d1a30696 | ||
|
|
130b3738cc | ||
|
|
92c7357615 | ||
|
|
c80f863334 | ||
|
|
4642c20179 | ||
|
|
5288eb22aa | ||
|
|
df8387a1a9 | ||
|
|
cc38c27f44 | ||
|
|
64f5357d69 | ||
|
|
51debb5649 | ||
|
|
b48d05a431 | ||
|
|
4e7f6b337d | ||
|
|
a509d99caf | ||
|
|
481e45fb64 | ||
|
|
e9038e1720 | ||
|
|
8fd9e582bf | ||
|
|
c1fd6f48a5 | ||
|
|
af615c7f4b | ||
|
|
bf0bc32d7a | ||
|
|
2d6b53e012 | ||
|
|
51271fea0f | ||
|
|
2deb473e0b | ||
|
|
23eeb33b3d | ||
|
|
f50dfaef45 | ||
|
|
55bb71e9d4 | ||
|
|
dab9357d28 | ||
|
|
27eb427245 | ||
|
|
260f3685d9 | ||
|
|
76e78fc0c3 | ||
|
|
1ac944fa02 | ||
|
|
986bc9b042 | ||
|
|
5a7942069b | ||
|
|
f6c6fc13ac | ||
|
|
1d8cfae89f | ||
|
|
787df51239 | ||
|
|
5e7f302a9c | ||
|
|
3d10fd40b5 | ||
|
|
57e3bf239c | ||
|
|
ccb09861e8 | ||
|
|
94551d75dd | ||
|
|
6e21218425 | ||
|
|
ff0fda48fc | ||
|
|
528aac7ad8 | ||
|
|
ab482e521d | ||
|
|
e08b61fa81 | ||
|
|
ce61bd1d2b | ||
|
|
7b708f7518 | ||
|
|
89ca50c7fc | ||
|
|
fb54899dcc | ||
|
|
0a625ad7dd | ||
|
|
d32e45efbe | ||
|
|
c77696bc78 | ||
|
|
736fde9e78 | ||
|
|
9c1ad92fed | ||
|
|
1a9fd2139d | ||
|
|
7661e7f27a | ||
|
|
f857b7fbf7 | ||
|
|
d94d12dbc5 | ||
|
|
700916276a | ||
|
|
834e52369c | ||
|
|
1ce53365de | ||
|
|
473f70668f | ||
|
|
0dbd2702f6 | ||
|
|
01e3764a9b | ||
|
|
ff9c81722a | ||
|
|
166aef7a02 | ||
|
|
78caf7646b | ||
|
|
1f99d40cec | ||
|
|
4c2912d3d5 | ||
|
|
45e6e06be5 | ||
|
|
fdbe3e05f3 | ||
|
|
7cc168f640 | ||
|
|
ff2d609c9b | ||
|
|
2689697b4c | ||
|
|
f90a0ea8ab | ||
|
|
caabe60f84 | ||
|
|
2bef4ed603 | ||
|
|
ee57be533b | ||
|
|
c5b7aaca25 | ||
|
|
7a1be905bb | ||
|
|
5798495a11 | ||
|
|
46171e2202 | ||
|
|
dd5c924ff5 | ||
|
|
30c4ab2976 | ||
|
|
26ea4d47b3 | ||
|
|
2732cd175c | ||
|
|
3e54b597be | ||
|
|
f10ebea209 | ||
|
|
2c6f3993cb | ||
|
|
708a696920 | ||
|
|
20bbb5d331 | ||
|
|
223e785b54 | ||
|
|
3d78692c59 | ||
|
|
5321a15dcf | ||
|
|
a452f8252a | ||
|
|
49267f09ac | ||
|
|
db47f35783 | ||
|
|
d48abf312c | ||
|
|
3b22ce4110 | ||
|
|
c521ca5bc9 | ||
|
|
3ddc1c6659 | ||
|
|
a8e19402b7 | ||
|
|
0927902b30 |
2
.github/workflows/pythonapp.yml
vendored
2
.github/workflows/pythonapp.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest, windows-latest]
|
||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
||||
python-version: ["3.7", "3.8", "3.9", "3.10"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,3 +4,5 @@ dist/
|
||||
build/
|
||||
*.egg-info/
|
||||
.github/
|
||||
.vscode/
|
||||
_config.yml
|
||||
|
||||
67
CHANGELOG
67
CHANGELOG
@@ -1,5 +1,72 @@
|
||||
jc changelog
|
||||
|
||||
20211221 v1.17.5
|
||||
- Add zipinfo parser tested on linux and macOS
|
||||
|
||||
20211207 v1.17.4
|
||||
- Add support for the NO_COLOR environment variable to set mono (http://no-color.org/)
|
||||
- Add -C option to force color output even when using pipes (overrides -m and NO_COLOR)
|
||||
|
||||
20211202 v1.17.3
|
||||
- Update parsers to exit with error if non-string input is detected (raise TypeError)
|
||||
- Update streaming parsers to exit with error if non-iterable input is detected (raise TypeError)
|
||||
- Simplify quiet-checking in parsers
|
||||
- Add iostat parser tested on linux
|
||||
- Add iostat streaming parser tested on linux
|
||||
|
||||
20211117 v1.17.2
|
||||
- Fix ping parser to add Alpine linux support
|
||||
- Fix netstat parser for older versions of netstat on linux
|
||||
- Fix df parser for cases where the filesystem field overflows the column length
|
||||
|
||||
20211030 v1.17.1
|
||||
- Fix file parser for gzip files
|
||||
- Fix uname parser for cases where the 'processor' and/or 'hardware_platform' fields are missing on linux
|
||||
- Fix uname parser on FreeBSD
|
||||
- Add lsusb parser tested on linux
|
||||
- Add CSV file streaming parser
|
||||
- Add testing for Python 3.10.0
|
||||
|
||||
20210923 v1.17.0
|
||||
- Note to Package Maintainers: please see note at 20210720 v1.16.0
|
||||
- Add wrapping of warning and error messages
|
||||
- Add vmstat parser tested on linux
|
||||
- Add support for streaming parsers
|
||||
- Add ls command streaming parser tested on linux, macOS, and freeBSD
|
||||
- Add ping command streaming parser tested on linux, macOS, and freeBSD
|
||||
- Add vmstat command streaming parser tested on linux
|
||||
- Add -u option to allow unbuffered output
|
||||
|
||||
20210830 v1.16.2
|
||||
- Note to Package Maintainers: please see note at 20210720 v1.16.0
|
||||
- Update sfdisk parser to support the -F option and newer versions of sfdisk
|
||||
|
||||
20210813 v1.16.1
|
||||
- Note to Package Maintainers: please see note at 20210720 v1.16.0
|
||||
- Fix issue with process substitution with the magic syntax
|
||||
- Fix issue with globs not including filenames with spaces with magic syntax
|
||||
- Fix stat parser to properly handle filenames with spaces on macOS/BSD
|
||||
|
||||
20210720 v1.16.0
|
||||
- Note to Package Maintainers:
|
||||
TL;DR: `/man/jc.1.gz` and `/jc/man/jc.1.gz` are deprecated and only `/man/jc.1` should be used.
|
||||
|
||||
The Man page in the PyPi source packages will be moving from `/jc/man/jc.1.gz` to `/man/jc.1`
|
||||
in version 1.17.0. For now the Man pages will be available in both locations, but be aware that
|
||||
the Man page at `/jc/man/jc.1.gz` is now considered deprecated.
|
||||
|
||||
Also, starting in v1.17.0, the Man page will no longer be compressed in the source package,
|
||||
therefore `/man/jc.1.gz` should also be considered deprecated and will no longer be available
|
||||
after v1.17.0. Please use `/man/jc.1` and compress downstream if you would like.
|
||||
- Include CHANGELOG in source distribution
|
||||
- Fix Man page location in source packages
|
||||
- Add sfdisk command parser tested on linux
|
||||
- Update unit test files to change the timezone when needed (POSIX only)
|
||||
- Binaries and DEB/RPM/MSI packages now include Python 3.9.5 interpreter
|
||||
|
||||
20210628 v1.15.6
|
||||
- Fix issue to only load local plugin parsers that have filenames that end in .py
|
||||
|
||||
20210520 v1.15.5
|
||||
- Fix issue where help and about information would not display if a 3rd party parser library was missing. (e.g. xmltodict)
|
||||
- Add more error message detail when encountering ParseError and LibraryNotFound exceptions
|
||||
|
||||
@@ -15,11 +15,12 @@ Pull requests are the best way to propose changes to the codebase (we use [Githu
|
||||
|
||||
1. Open an issue to discuss the new feature, bug fix, or parser before opening a pull request. For new parsers, it is important to agree upon a schema before developing the parser.
|
||||
2. Fork the repo and create your branch from `dev`, if available, otherwise `master`.
|
||||
3. If you've added code that should be tested, add tests. All new parsers should have several sample outputs and tests.
|
||||
4. Documentation is auto-generated from docstrings, so ensure they are clear and accurate.
|
||||
5. Ensure the test suite passes. (Note: "**America/Los_Angeles**" timezone should be configured on the test system)
|
||||
6. Make sure your code lints.
|
||||
7. Issue that pull request!
|
||||
3. For new parsers: Use the [`jc/parsers/foo.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo.py) or [`jc/parsers/foo_s.py (streaming)`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo_s.py) parsers as a template to get started. You can even place a new parser python module file in the [parser plugin directory](https://github.com/kellyjonbrazil/jc#custom-parsers) to get started right away with just a standard `jc` installation.
|
||||
4. If you've added code that should be tested, add tests. All new parsers should have several sample outputs and tests.
|
||||
5. Documentation is auto-generated from docstrings, so ensure they are clear and accurate.
|
||||
6. Ensure the test suite passes. (Note: "**America/Los_Angeles**" timezone should be configured on the test system)
|
||||
7. Make sure your code lints.
|
||||
8. Issue that pull request!
|
||||
|
||||
## Parser Schema Guidelines
|
||||
- Try to keep the schema as flat as possible - typically a list of flat dictionaries
|
||||
@@ -31,31 +32,31 @@ This will make it easier to use tools like `jq` without requiring escaping of sp
|
||||
**Examples**
|
||||
|
||||
Bad:
|
||||
```
|
||||
```json
|
||||
{
|
||||
"Interface 1": [
|
||||
192.168.1.1,
|
||||
172.16.1.1
|
||||
"192.168.1.1",
|
||||
"172.16.1.1"
|
||||
],
|
||||
"Wifi Interface 1": [
|
||||
10.1.1.1
|
||||
"10.1.1.1"
|
||||
]
|
||||
}
|
||||
```
|
||||
Good:
|
||||
```
|
||||
```json
|
||||
[
|
||||
{
|
||||
"interface": "Interface 1",
|
||||
"ip_addresses": [
|
||||
192.168.1.1,
|
||||
172.16.1.1
|
||||
"192.168.1.1",
|
||||
"172.16.1.1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"interface": "Wifi Interface 1",
|
||||
"ip_addresses": [
|
||||
10.1.1.1
|
||||
"10.1.1.1"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
266
EXAMPLES.md
266
EXAMPLES.md
@@ -1516,6 +1516,50 @@ cat example.ini | jc --ini -p
|
||||
}
|
||||
}
|
||||
```
|
||||
### iostat
|
||||
```bash
|
||||
$ iostat | jc --iostat -p # or: jc -p iostat
|
||||
```
|
||||
```json
|
||||
[
|
||||
{
|
||||
"percent_user": 0.15,
|
||||
"percent_nice": 0.0,
|
||||
"percent_system": 0.18,
|
||||
"percent_iowait": 0.0,
|
||||
"percent_steal": 0.0,
|
||||
"percent_idle": 99.67,
|
||||
"type": "cpu"
|
||||
},
|
||||
{
|
||||
"device": "sda",
|
||||
"tps": 0.29,
|
||||
"kb_read_s": 7.22,
|
||||
"kb_wrtn_s": 1.25,
|
||||
"kb_read": 194341,
|
||||
"kb_wrtn": 33590,
|
||||
"type": "device"
|
||||
},
|
||||
{
|
||||
"device": "dm-0",
|
||||
"tps": 0.29,
|
||||
"kb_read_s": 5.99,
|
||||
"kb_wrtn_s": 1.17,
|
||||
"kb_read": 161361,
|
||||
"kb_wrtn": 31522,
|
||||
"type": "device"
|
||||
},
|
||||
{
|
||||
"device": "dm-1",
|
||||
"tps": 0.0,
|
||||
"kb_read_s": 0.08,
|
||||
"kb_wrtn_s": 0.0,
|
||||
"kb_read": 2204,
|
||||
"kb_wrtn": 0,
|
||||
"type": "device"
|
||||
}
|
||||
]
|
||||
```
|
||||
### iptables
|
||||
```bash
|
||||
iptables --line-numbers -v -L -t nat | jc --iptables -p # or: jc -p iptables --line-numbers -v -L -t nat
|
||||
@@ -1917,6 +1961,128 @@ lsof | jc --lsof -p # or: jc -p lsof
|
||||
}
|
||||
]
|
||||
```
|
||||
### lsusb
|
||||
```bash
|
||||
lsusb -v | jc --lsusb -p # or: jc -p lsusb -v
|
||||
```
|
||||
```json
|
||||
[
|
||||
{
|
||||
"bus": "002",
|
||||
"device": "001",
|
||||
"id": "1d6b:0001",
|
||||
"description": "Linux Foundation 1.1 root hub",
|
||||
"device_descriptor": {
|
||||
"bLength": {
|
||||
"value": "18"
|
||||
},
|
||||
"bDescriptorType": {
|
||||
"value": "1"
|
||||
},
|
||||
"bcdUSB": {
|
||||
"value": "1.10"
|
||||
},
|
||||
...
|
||||
"bNumConfigurations": {
|
||||
"value": "1"
|
||||
},
|
||||
"configuration_descriptor": {
|
||||
"bLength": {
|
||||
"value": "9"
|
||||
},
|
||||
...
|
||||
"iConfiguration": {
|
||||
"value": "0"
|
||||
},
|
||||
"bmAttributes": {
|
||||
"value": "0xe0",
|
||||
"attributes": [
|
||||
"Self Powered",
|
||||
"Remote Wakeup"
|
||||
]
|
||||
},
|
||||
"MaxPower": {
|
||||
"description": "0mA"
|
||||
},
|
||||
"interface_descriptors": [
|
||||
{
|
||||
"bLength": {
|
||||
"value": "9"
|
||||
},
|
||||
...
|
||||
"bInterfaceProtocol": {
|
||||
"value": "0",
|
||||
"description": "Full speed (or root) hub"
|
||||
},
|
||||
"iInterface": {
|
||||
"value": "0"
|
||||
},
|
||||
"endpoint_descriptors": [
|
||||
{
|
||||
"bLength": {
|
||||
"value": "7"
|
||||
},
|
||||
...
|
||||
"bmAttributes": {
|
||||
"value": "3",
|
||||
"attributes": [
|
||||
"Transfer Type Interrupt",
|
||||
"Synch Type None",
|
||||
"Usage Type Data"
|
||||
]
|
||||
},
|
||||
"wMaxPacketSize": {
|
||||
"value": "0x0002",
|
||||
"description": "1x 2 bytes"
|
||||
},
|
||||
"bInterval": {
|
||||
"value": "255"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"hub_descriptor": {
|
||||
"bLength": {
|
||||
"value": "9"
|
||||
},
|
||||
...
|
||||
"wHubCharacteristic": {
|
||||
"value": "0x000a",
|
||||
"attributes": [
|
||||
"No power switching (usb 1.0)",
|
||||
"Per-port overcurrent protection"
|
||||
]
|
||||
},
|
||||
...
|
||||
"hub_port_status": {
|
||||
"Port 1": {
|
||||
"value": "0000.0103",
|
||||
"attributes": [
|
||||
"power",
|
||||
"enable",
|
||||
"connect"
|
||||
]
|
||||
},
|
||||
"Port 2": {
|
||||
"value": "0000.0103",
|
||||
"attributes": [
|
||||
"power",
|
||||
"enable",
|
||||
"connect"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"device_status": {
|
||||
"value": "0x0001",
|
||||
"description": "Self Powered"
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
### mount
|
||||
```bash
|
||||
mount | jc --mount -p # or: jc -p mount
|
||||
@@ -2556,6 +2722,75 @@ rpm_qia | jc --rpm_qi -p # or: jc -p rpm -qia
|
||||
}
|
||||
]
|
||||
```
|
||||
### sfdisk
|
||||
```bash
|
||||
sfdisk -l | jc --sfdisk -p # or jc -p sfdisk -l
|
||||
```
|
||||
```json
|
||||
[
|
||||
{
|
||||
"disk": "/dev/sda",
|
||||
"cylinders": 2610,
|
||||
"heads": 255,
|
||||
"sectors_per_track": 63,
|
||||
"units": "cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0",
|
||||
"partitions": [
|
||||
{
|
||||
"device": "/dev/sda1",
|
||||
"boot": true,
|
||||
"start": 0,
|
||||
"end": 130,
|
||||
"cyls": 131,
|
||||
"blocks": 1048576,
|
||||
"id": "83",
|
||||
"system": "Linux"
|
||||
},
|
||||
{
|
||||
"device": "/dev/sda2",
|
||||
"boot": false,
|
||||
"start": 130,
|
||||
"end": 2610,
|
||||
"cyls": 2481,
|
||||
"blocks": 19921920,
|
||||
"id": "8e",
|
||||
"system": "Linux LVM"
|
||||
},
|
||||
{
|
||||
"device": "/dev/sda3",
|
||||
"boot": false,
|
||||
"start": 0,
|
||||
"end": null,
|
||||
"cyls": 0,
|
||||
"blocks": 0,
|
||||
"id": "0",
|
||||
"system": "Empty"
|
||||
},
|
||||
{
|
||||
"device": "/dev/sda4",
|
||||
"boot": false,
|
||||
"start": 0,
|
||||
"end": null,
|
||||
"cyls": 0,
|
||||
"blocks": 0,
|
||||
"id": "0",
|
||||
"system": "Empty"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"disk": "/dev/mapper/centos-root",
|
||||
"cylinders": 2218,
|
||||
"heads": 255,
|
||||
"sectors_per_track": 63
|
||||
},
|
||||
{
|
||||
"disk": "/dev/mapper/centos-swap",
|
||||
"cylinders": 261,
|
||||
"heads": 255,
|
||||
"sectors_per_track": 63
|
||||
}
|
||||
]
|
||||
```
|
||||
### /etc/shadow file
|
||||
```bash
|
||||
cat /etc/shadow | jc --shadow -p
|
||||
@@ -3558,5 +3793,36 @@ cat istio.yaml | jc --yaml -p
|
||||
}
|
||||
]
|
||||
```
|
||||
### zipinfo
|
||||
```bash
|
||||
zipinfo file.zip | jc --zipinfo -p # or: jc -p zipinfo file.zip
|
||||
```
|
||||
```json
|
||||
[
|
||||
{
|
||||
"archive": "file.zip",
|
||||
"size": 4116,
|
||||
"size_unit": "bytes",
|
||||
"number_entries": 1,
|
||||
"number_files": 1,
|
||||
"bytes_uncompressed": 11837,
|
||||
"bytes_compressed": 3966,
|
||||
"percent_compressed": 66.5,
|
||||
"files": [
|
||||
{
|
||||
"flags": "-rw-r--r--",
|
||||
"zipversion": "2.1",
|
||||
"zipunder": "unx",
|
||||
"filesize": 11837,
|
||||
"type": "bX",
|
||||
"method": "defN",
|
||||
"date": "21-Dec-08",
|
||||
"time": "20:50",
|
||||
"filename": "compressed_file"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
© 2019-2021 Kelly Brazil
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
include jc/man/jc.1.gz
|
||||
include man/jc.1
|
||||
include CHANGELOG
|
||||
|
||||
123
README.md
123
README.md
@@ -1,9 +1,9 @@
|
||||

|
||||

|
||||
|
||||
> Try the new `jc` [web demo](https://jc-web-demo.herokuapp.com/)!
|
||||
> Try the `jc` [web demo](https://jc-web-demo.herokuapp.com/)
|
||||
|
||||
> JC is [now available](https://galaxy.ansible.com/community/general) as an Ansible filter plugin in the `community.general` collection! See this [blog post](https://blog.kellybrazil.com/2020/08/30/parsing-command-output-in-ansible-with-jc/) for an example.
|
||||
> JC is [now available](https://galaxy.ansible.com/community/general) as an Ansible filter plugin in the `community.general` collection. See this [blog post](https://blog.kellybrazil.com/2020/08/30/parsing-command-output-in-ansible-with-jc/) for an example.
|
||||
|
||||
# JC
|
||||
JSON CLI output utility
|
||||
@@ -19,7 +19,7 @@ dig example.com | jc --dig
|
||||
39049,"data":"93.184.216.34"}],"query_time":49,"server":"2600:1700:bab0:d40::1#53(2600:1700:bab0:d40::1)","when":
|
||||
"Fri Apr 16 16:09:00 PDT 2021","rcvd":56,"when_epoch":1618614540,"when_epoch_utc":null}]
|
||||
```
|
||||
This allows further command-line processing of output with tools like `jq` by piping commands:
|
||||
This allows further command-line processing of output with tools like `jq` or [`jello`](https://github.com/kellyjonbrazil/jello) by piping commands:
|
||||
```bash
|
||||
$ dig example.com | jc --dig | jq -r '.[].answer[].data'
|
||||
93.184.216.34
|
||||
@@ -31,28 +31,13 @@ $ jc dig example.com | jq -r '.[].answer[].data'
|
||||
```
|
||||
The `jc` parsers can also be used as python modules. In this case the output will be a python dictionary, or list of dictionaries, instead of JSON:
|
||||
```python
|
||||
>>> import subprocess
|
||||
>>> import jc.parsers.dig
|
||||
>>>
|
||||
>>> data = '''; <<>> DiG 9.10.6 <<>> example.com
|
||||
... ;; global options: +cmd
|
||||
... ;; Got answer:
|
||||
... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64612
|
||||
... ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
|
||||
...
|
||||
... ;; OPT PSEUDOSECTION:
|
||||
... ; EDNS: version: 0, flags:; udp: 4096
|
||||
... ;; QUESTION SECTION:
|
||||
... ;example.com. IN A
|
||||
...
|
||||
... ;; ANSWER SECTION:
|
||||
... example.com. 29658 IN A 93.184.216.34
|
||||
...
|
||||
... ;; Query time: 52 msec
|
||||
... ;; SERVER: 2600:1700:bab0:d40::1#53(2600:1700:bab0:d40::1)
|
||||
... ;; WHEN: Fri Apr 16 16:13:00 PDT 2021
|
||||
... ;; MSG SIZE rcvd: 56'''
|
||||
>>> cmd_output = subprocess.check_output(['dig', 'example.com'], text=True)
|
||||
>>> data = jc.parsers.dig.parse(cmd_output)
|
||||
>>>
|
||||
>>> jc.parsers.dig.parse(data)
|
||||
>>> data
|
||||
[{'id': 64612, 'opcode': 'QUERY', 'status': 'NOERROR', 'flags': ['qr', 'rd', 'ra'], 'query_num': 1, 'answer_num':
|
||||
1, 'authority_num': 0, 'additional_num': 1, 'opt_pseudosection': {'edns': {'version': 0, 'flags': [], 'udp':
|
||||
4096}}, 'question': {'name': 'example.com.', 'class': 'IN', 'type': 'A'}, 'answer': [{'name': 'example.com.',
|
||||
@@ -60,7 +45,7 @@ The `jc` parsers can also be used as python modules. In this case the output wil
|
||||
'2600:1700:bab0:d40::1#53(2600:1700:bab0:d40::1)', 'when': 'Fri Apr 16 16:13:00 PDT 2021', 'rcvd': 56,
|
||||
'when_epoch': 1618614780, 'when_epoch_utc': None}]
|
||||
```
|
||||
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 available. 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()`.
|
||||
|
||||
@@ -75,6 +60,8 @@ See also:
|
||||
- [libxo on FreeBSD](http://juniper.github.io/libxo/libxo-manual.html)
|
||||
- [powershell](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertto-json?view=powershell-7)
|
||||
- [blog: linux apps should have a json flag](https://thomashunter.name/posts/2012-06-06-linux-cli-apps-should-have-a-json-flag)
|
||||
- [Hacker News discussion](https://news.ycombinator.com/item?id=28266193)
|
||||
- [Reddit discussion](https://www.reddit.com/r/programming/comments/pa4cbb/bringing_the_unix_philosophy_to_the_21st_century/)
|
||||
|
||||
Use Cases:
|
||||
- [Bash scripting](https://blog.kellybrazil.com/2021/04/12/practical-json-at-the-command-line/)
|
||||
@@ -83,7 +70,7 @@ Use Cases:
|
||||
- [Nornir command output parsing](https://blog.kellybrazil.com/2020/12/09/parsing-command-output-in-nornir-with-jc/)
|
||||
|
||||
## Installation
|
||||
There are several ways to get `jc`. You can install via `pip`; other OS package repositories like `apt-get`, `dnf`, `zypper`, `pacman`, `nix-env`, `guix`, `brew`, or `portsnap`; via DEB, RPM, and MSI packaged binaries for linux and Windows; or by downloading the correct binary for your architecture and running it anywhere on your filesystem.
|
||||
There are several ways to get `jc`. You can install via `pip`, OS package repositories, via DEB/RPM/MSI packaged binaries for linux and Windows, or by downloading the correct binary for your architecture and running it anywhere on your filesystem.
|
||||
|
||||
### Pip (macOS, linux, unix, Windows)
|
||||
```bash
|
||||
@@ -100,7 +87,7 @@ pip3 install jc
|
||||
| Arch linux | `pacman -S jc` |
|
||||
| NixOS linux | `nix-env -iA nixpkgs.jc` or `nix-env -iA nixos.jc` |
|
||||
| Guix System linux | `guix install jc` |
|
||||
| MacOS | `brew install jc` |
|
||||
| macOS | `brew install jc` |
|
||||
| FreeBSD | `portsnap fetch update && cd /usr/ports/textproc/py-jc && make install clean` |
|
||||
| Ansible filter plugin | `ansible-galaxy collection install community.general` |
|
||||
|
||||
@@ -128,6 +115,7 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio
|
||||
- `--crontab` enables the `crontab` command and file parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/crontab))
|
||||
- `--crontab-u` enables the `crontab` file parser with user support ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/crontab_u))
|
||||
- `--csv` enables the CSV file parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/csv))
|
||||
- `--csv-s` enables the CSV file streaming parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/csv_s))
|
||||
- `--date` enables the `date` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/date))
|
||||
- `--df` enables the `df` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/df))
|
||||
- `--dig` enables the `dig` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/dig))
|
||||
@@ -150,25 +138,31 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio
|
||||
- `--id` enables the `id` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/id))
|
||||
- `--ifconfig` enables the `ifconfig` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ifconfig))
|
||||
- `--ini` enables the INI file parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ini))
|
||||
- `--iostat` enables the `iostat` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/iostat))
|
||||
- `--iostat-s` enables the `iostat` command streaming parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/iostat_s))
|
||||
- `--iptables` enables the `iptables` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/iptables))
|
||||
- `--iw-scan` enables the `iw dev [device] scan` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/iw_scan))
|
||||
- `--jobs` enables the `jobs` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/jobs))
|
||||
- `--kv` enables the Key/Value file parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/kv))
|
||||
- `--last` enables the `last` and `lastb` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/last))
|
||||
- `--ls` enables the `ls` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ls))
|
||||
- `--ls-s` enables the `ls` command streaming parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ls_s))
|
||||
- `--lsblk` enables the `lsblk` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/lsblk))
|
||||
- `--lsmod` enables the `lsmod` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/lsmod))
|
||||
- `--lsof` enables the `lsof` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/lsof))
|
||||
- `--lsusb` enables the `lsusb` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/lsusb))
|
||||
- `--mount` enables the `mount` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/mount))
|
||||
- `--netstat` enables the `netstat` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/netstat))
|
||||
- `--ntpq` enables the `ntpq -p` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ntpq))
|
||||
- `--passwd` enables the `/etc/passwd` file parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/passwd))
|
||||
- `--ping` enables the `ping` and `ping6` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ping))
|
||||
- `--ping-s` enables the `ping` and `ping6` command streaming parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ping_s))
|
||||
- `--pip-list` enables the `pip list` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/pip_list))
|
||||
- `--pip-show` enables the `pip show` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/pip_show))
|
||||
- `--ps` enables the `ps` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ps))
|
||||
- `--route` enables the `route` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/route))
|
||||
- `--rpm-qi` enables the `rpm -qi` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/rpm_qi))
|
||||
- `--sfdisk` enables the `sfdisk` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/sfdisk))
|
||||
- `--shadow` enables the `/etc/shadow` file parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/shadow))
|
||||
- `--ss` enables the `ss` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ss))
|
||||
- `--stat` enables the `stat` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/stat))
|
||||
@@ -187,20 +181,25 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio
|
||||
- `--uname` enables the `uname -a` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/uname))
|
||||
- `--upower` enables the `upower` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/upower))
|
||||
- `--uptime` enables the `uptime` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/uptime))
|
||||
- `--vmstat` enables the `vmstat` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/vmstat))
|
||||
- `--vmstat-s` enables the `vmstat` command streaming parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/vmstat_s))
|
||||
- `--w` enables the `w` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/w))
|
||||
- `--wc` enables the `wc` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/wc))
|
||||
- `--who` enables the `who` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/who))
|
||||
- `--xml` enables the XML file parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/xml))
|
||||
- `--yaml` enables the YAML file parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/yaml))
|
||||
- `--zipinfo` enables the `zipinfo` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/zipinfo))
|
||||
|
||||
### Options
|
||||
- `-a` about `jc`. Prints information about `jc` and the parsers (in JSON, of course!)
|
||||
- `-C` force color output even when using pipes (overrides `-m` and the `NO_COLOR` env variable)
|
||||
- `-d` debug mode. Prints trace messages if parsing issues are encountered (use `-dd` for verbose debugging)
|
||||
- `-h` `jc` help. Use `jc -h --parser_name` for parser documentation
|
||||
- `-h` help. Use `jc -h --parser_name` for parser documentation
|
||||
- `-m` monochrome JSON output
|
||||
- `-p` pretty format the JSON output
|
||||
- `-q` quiet mode. Suppresses parser warning messages
|
||||
- `-q` quiet mode. Suppresses parser warning messages (use `-qq` to ignore streaming parser errors)
|
||||
- `-r` raw output. Provides a more literal JSON output, typically with string values and no additional semantic processing
|
||||
- `-u` unbuffer output
|
||||
- `-v` version information
|
||||
|
||||
### Exit Codes
|
||||
@@ -232,6 +231,67 @@ or
|
||||
JC_COLORS=default,default,default,default
|
||||
```
|
||||
|
||||
### Disable Colors via Environment Variable
|
||||
You can set the [`NO_COLOR`](http://no-color.org/) environment variable to any value to disable color output in `jc`. Note that using the `-C` option to force color output will override both the `NO_COLOR` environment variable and the `-m` option.
|
||||
|
||||
### Streaming Parsers
|
||||
Most parsers load all of the data from STDIN, parse it, then output the entire JSON document serially. There are some streaming parsers (e.g. `ls-s` and `ping-s`) that immediately start processing and outputing the data line-by-line as [JSON Lines](https://jsonlines.org/) (aka [NDJSON](http://ndjson.org/)) while it is being received from STDIN. This can significantly reduce the amount of memory required to parse large amounts of command output (e.g. `ls -lR /`) and can sometimes process the data more quickly. Streaming parsers have slightly different behavior than standard parsers as outlined below.
|
||||
|
||||
> Note: Streaming parsers cannot be used with the "magic" syntax
|
||||
|
||||
#### Ignoring Errors
|
||||
|
||||
You may want to ignore parsing errors when using streaming parsers since these may be used in long-lived processing pipelines and errors can break the pipe. To ignore parsing errors, use the `-qq` cli option or the `ignore_exceptions=True` argument with the `parse()` function. This will add a `_jc_meta` object to the JSON output with a `success` attribute. If `success` is `true`, then there were no issues parsing the line. If `success` is `false`, then a parsing issue was found and `error` and `line` fields will be added to include a short error description and the contents of the unparsable line, respectively:
|
||||
|
||||
Successfully parsed line with `-qq` option:
|
||||
```json
|
||||
{
|
||||
"command_data": "data",
|
||||
"_jc_meta": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
```
|
||||
Unsuccessfully parsed line with `-qq` option:
|
||||
```json
|
||||
{
|
||||
"_jc_meta": {
|
||||
"success": false,
|
||||
"error": "error message",
|
||||
"line": "original line data"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Unbuffering Output
|
||||
|
||||
Most operating systems will buffer output that is being piped from process to process. The buffer is usually around 4KB. When viewing the output in the terminal the OS buffer is not engaged so output is immediately displayed on the screen. When piping multiple processes together, though, it may seem as if the output is hanging when the input data is very slow (e.g. `ping`):
|
||||
```
|
||||
$ ping 1.1.1.1 | jc --ping-s | jq
|
||||
<slow output>
|
||||
```
|
||||
This is because the OS engages the 4KB buffer between `jc` and `jq` in this example. To display the data on the terminal in realtime, you can disable the buffer with the `-u` (unbuffer) cli option:
|
||||
```
|
||||
$ ping 1.1.1.1 | jc --ping-s -u | jq
|
||||
{"type":"reply","pattern":null,"timestamp":null,"bytes":"64","response_ip":"1.1.1.1","icmp_seq":"1","ttl":"128","time_ms":"24.6","duplicate":false}
|
||||
{"type":"reply","pattern":null,"timestamp":null,"bytes":"64","response_ip":"1.1.1.1","icmp_seq":"2","ttl":"128","time_ms":"26.8","duplicate":false}
|
||||
...
|
||||
```
|
||||
> Note: Unbuffered output can be slower for large data streams.
|
||||
|
||||
#### Using Streaming Parsers as Python Modules
|
||||
|
||||
Streaming parsers accept any iterable object and return a generator iterator object allowing lazy processing of the data. The input data should iterate on lines of string data. Examples of good input data are `sys.stdin` or `str.splitlines()`.
|
||||
|
||||
To use the generator object in your code, simply loop through it or use the [next()](https://docs.python.org/3/library/functions.html#next) builtin function:
|
||||
```python
|
||||
import jc.parsers.ls_s
|
||||
|
||||
result = jc.parsers.ls_s.parse(ls_command_output.splitlines())
|
||||
for item in result:
|
||||
print(item["filename"])
|
||||
```
|
||||
|
||||
### Custom Parsers
|
||||
Custom local parser plugins may be placed in a `jc/jcparsers` folder in your local **"App data directory"**:
|
||||
|
||||
@@ -239,14 +299,15 @@ Custom local parser plugins may be placed in a `jc/jcparsers` folder in your loc
|
||||
- macOS: `$HOME/Library/Application Support/jc/jcparsers`
|
||||
- Windows: `$LOCALAPPDATA\jc\jc\jcparsers`
|
||||
|
||||
Local parser plugins are standard python module files. Use the [`jc/parsers/foo.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo.py) parser as a template and simply place a `.py` file in the `jcparsers` subfolder.
|
||||
Local parser plugins are standard python module files. Use the [`jc/parsers/foo.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo.py) or [`jc/parsers/foo_s.py (streaming)`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo_s.py) parser as a template and simply place a `.py` file in the `jcparsers` subfolder.
|
||||
|
||||
Local plugin filenames must be valid python module names, therefore must consist entirely of alphanumerics and start with a letter. Local plugins may override default parsers.
|
||||
|
||||
> Note: The application data directory follows the [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)
|
||||
|
||||
### Caveats
|
||||
**Locale:**
|
||||
|
||||
#### Locale
|
||||
|
||||
For best results set the `LANG` locale environment variable to `C` or `en_US.UTF-8`. For example, either by setting directly on the command-line:
|
||||
```
|
||||
@@ -257,7 +318,7 @@ or by exporting to the environment before running commands:
|
||||
$ export LANG=C
|
||||
```
|
||||
|
||||
**Timezones:**
|
||||
#### Timezones
|
||||
|
||||
Some parsers have calculated epoch timestamp fields added to the output. Unless a timestamp field name has a `_utc` suffix it is considered naive. (i.e. based on the local timezone of the system the `jc` parser was run on).
|
||||
|
||||
@@ -291,7 +352,7 @@ Tested on:
|
||||
- Windows 2019 Server
|
||||
|
||||
## Contributions
|
||||
Feel free to add/improve code or parsers! You can use the [`jc/parsers/foo.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo.py) parser as a template and submit your parser with a pull request.
|
||||
Feel free to add/improve code or parsers! You can use the [`jc/parsers/foo.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo.py) or [`jc/parsers/foo_s.py (streaming)`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo_s.py) parsers as a template and submit your parser with a pull request.
|
||||
|
||||
Please see the [Contributing Guidelines](https://github.com/kellyjonbrazil/jc/blob/master/CONTRIBUTING.md) for more information.
|
||||
|
||||
|
||||
@@ -252,4 +252,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -105,4 +105,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: darwin
|
||||
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -133,4 +133,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: darwin
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -142,4 +142,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, aix, freebsd, darwin
|
||||
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -145,4 +145,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -79,4 +79,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, aix, freebsd
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -22,8 +22,10 @@ Schema:
|
||||
|
||||
{
|
||||
"variables": [
|
||||
"name": string,
|
||||
"value": string
|
||||
{
|
||||
"name": string,
|
||||
"value": string
|
||||
}
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
@@ -195,4 +197,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, aix, freebsd
|
||||
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -18,8 +18,10 @@ Schema:
|
||||
|
||||
{
|
||||
"variables": [
|
||||
"name": string,
|
||||
"value": string
|
||||
{
|
||||
"name": string,
|
||||
"value": string
|
||||
}
|
||||
],
|
||||
"schedule": [
|
||||
{
|
||||
@@ -191,4 +193,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, aix, freebsd
|
||||
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -99,4 +99,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
85
docs/parsers/csv_s.md
Normal file
85
docs/parsers/csv_s.md
Normal file
@@ -0,0 +1,85 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
|
||||
# jc.parsers.csv_s
|
||||
jc - JSON CLI output utility `csv` file streaming parser
|
||||
|
||||
> This streaming parser outputs JSON Lines
|
||||
|
||||
The `csv` streaming parser will attempt to automatically detect the delimiter character. If the delimiter cannot be detected it will default to comma. The first row of the file must be a header row.
|
||||
|
||||
Note: The first 100 rows are read into memory to enable delimiter detection, then the rest of the rows are loaded lazily.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ cat file.csv | jc --csv-s
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc.parsers.csv_s
|
||||
result = jc.parsers.csv_s.parse(csv_output.splitlines()) # result is an iterable object
|
||||
for item in result:
|
||||
# do something
|
||||
|
||||
Schema:
|
||||
|
||||
csv file converted to a Dictionary: https://docs.python.org/3/library/csv.html
|
||||
|
||||
{
|
||||
"column_name1": string,
|
||||
"column_name2": string,
|
||||
"_jc_meta": # This object only exists if using -qq or ignore_exceptions=True
|
||||
{
|
||||
"success": boolean, # true if successfully parsed, false if error
|
||||
"error": string, # exists if "success" is false
|
||||
"line": string # exists if "success" is false
|
||||
}
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat homes.csv
|
||||
"Sell", "List", "Living", "Rooms", "Beds", "Baths", "Age", "Acres", "Taxes"
|
||||
142, 160, 28, 10, 5, 3, 60, 0.28, 3167
|
||||
175, 180, 18, 8, 4, 1, 12, 0.43, 4033
|
||||
129, 132, 13, 6, 3, 1, 41, 0.33, 1471
|
||||
...
|
||||
|
||||
$ cat homes.csv | jc --csv-s
|
||||
{"Sell":"142","List":"160","Living":"28","Rooms":"10","Beds":"5","Baths":"3","Age":"60","Acres":"0.28","Taxes":"3167"}
|
||||
{"Sell":"175","List":"180","Living":"18","Rooms":"8","Beds":"4","Baths":"1","Age":"12","Acres":"0.43","Taxes":"4033"}
|
||||
{"Sell":"129","List":"132","Living":"13","Rooms":"6","Beds":"3","Baths":"1","Age":"41","Acres":"0.33","Taxes":"1471"}
|
||||
...
|
||||
|
||||
|
||||
## info
|
||||
```python
|
||||
info()
|
||||
```
|
||||
Provides parser metadata (version, author, etc.)
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False, ignore_exceptions=False)
|
||||
```
|
||||
|
||||
Main text parsing generator function. Returns an iterator object.
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (iterable) line-based text data to parse (e.g. sys.stdin or str.splitlines())
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
ignore_exceptions: (boolean) ignore parsing exceptions if True
|
||||
|
||||
Yields:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
Returns:
|
||||
|
||||
Iterator object
|
||||
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -96,4 +96,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 2.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 2.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -122,4 +122,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.9 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -341,4 +341,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, aix, freebsd, darwin, win32, cygwin
|
||||
|
||||
Version 2.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 2.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -143,4 +143,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: win32
|
||||
|
||||
Version 1.3 by Rasheed Elsaleh (rasheed@rebelliondefense.com)
|
||||
Version 1.4 by Rasheed Elsaleh (rasheed@rebelliondefense.com)
|
||||
|
||||
@@ -150,4 +150,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -155,4 +155,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -112,4 +112,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, aix, freebsd
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -95,4 +95,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -87,4 +87,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, aix, freebsd, darwin
|
||||
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -115,4 +115,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, freebsd
|
||||
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -97,4 +97,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -110,4 +110,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, freebsd
|
||||
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -134,4 +134,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, aix, freebsd
|
||||
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -102,4 +102,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, aix, freebsd
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -62,4 +62,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, aix, freebsd
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -93,4 +93,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, aix, freebsd
|
||||
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -342,4 +342,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -85,4 +85,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, aix, freebsd
|
||||
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -99,4 +99,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -130,4 +130,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, aix, freebsd
|
||||
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -211,4 +211,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, aix, freebsd, darwin
|
||||
|
||||
Version 1.10 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.11 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -90,4 +90,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
187
docs/parsers/iostat.md
Normal file
187
docs/parsers/iostat.md
Normal file
@@ -0,0 +1,187 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
|
||||
# jc.parsers.iostat
|
||||
jc - JSON CLI output utility `iostat` command output parser
|
||||
|
||||
Note: `iostat` version 11 and higher include a JSON output option
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ iostat | jc --iostat
|
||||
|
||||
or
|
||||
|
||||
$ jc iostat
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc.parsers.iostat
|
||||
result = jc.parsers.iostat.parse(iostat_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"type": string,
|
||||
"percent_user": float,
|
||||
"percent_nice": float,
|
||||
"percent_system": float,
|
||||
"percent_iowait": float,
|
||||
"percent_steal": float,
|
||||
"percent_idle": float,
|
||||
"device": string,
|
||||
"tps": float,
|
||||
"kb_read_s": float,
|
||||
"mb_read_s": float,
|
||||
"kb_wrtn_s": float,
|
||||
"mb_wrtn_s": float,
|
||||
"kb_read": integer,
|
||||
"mb_read": integer,
|
||||
"kb_wrtn": integer,
|
||||
"mb_wrtn": integer,
|
||||
'kb_dscd': integer,
|
||||
'mb_dscd': integer,
|
||||
"rrqm_s": float,
|
||||
"wrqm_s": float,
|
||||
"r_s": float,
|
||||
"w_s": float,
|
||||
"rmb_s": float,
|
||||
"rkb_s": float,
|
||||
"wmb_s": float,
|
||||
"wkb_s": float,
|
||||
"avgrq_sz": float,
|
||||
"avgqu_sz": float,
|
||||
"await": float,
|
||||
"r_await": float,
|
||||
"w_await": float,
|
||||
"svctm": float,
|
||||
"aqu_sz": float,
|
||||
"rareq_sz": float,
|
||||
"wareq_sz": float,
|
||||
"d_s": float,
|
||||
"dkb_s": float,
|
||||
"dmb_s": float,
|
||||
"drqm_s": float,
|
||||
"percent_drqm": float,
|
||||
"d_await": float,
|
||||
"dareq_sz": float,
|
||||
"f_s": float,
|
||||
"f_await": float,
|
||||
"kb_dscd_s": float,
|
||||
"mb_dscd_s": float,
|
||||
"percent_util": float,
|
||||
"percent_rrqm": float,
|
||||
"percent_wrqm": float
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ iostat | jc --iostat -p
|
||||
[
|
||||
{
|
||||
"percent_user": 0.15,
|
||||
"percent_nice": 0.0,
|
||||
"percent_system": 0.18,
|
||||
"percent_iowait": 0.0,
|
||||
"percent_steal": 0.0,
|
||||
"percent_idle": 99.67,
|
||||
"type": "cpu"
|
||||
},
|
||||
{
|
||||
"device": "sda",
|
||||
"tps": 0.29,
|
||||
"kb_read_s": 7.22,
|
||||
"kb_wrtn_s": 1.25,
|
||||
"kb_read": 194341,
|
||||
"kb_wrtn": 33590,
|
||||
"type": "device"
|
||||
},
|
||||
{
|
||||
"device": "dm-0",
|
||||
"tps": 0.29,
|
||||
"kb_read_s": 5.99,
|
||||
"kb_wrtn_s": 1.17,
|
||||
"kb_read": 161361,
|
||||
"kb_wrtn": 31522,
|
||||
"type": "device"
|
||||
},
|
||||
{
|
||||
"device": "dm-1",
|
||||
"tps": 0.0,
|
||||
"kb_read_s": 0.08,
|
||||
"kb_wrtn_s": 0.0,
|
||||
"kb_read": 2204,
|
||||
"kb_wrtn": 0,
|
||||
"type": "device"
|
||||
}
|
||||
]
|
||||
|
||||
$ iostat | jc --iostat -p -r
|
||||
[
|
||||
{
|
||||
"percent_user": "0.15",
|
||||
"percent_nice": "0.00",
|
||||
"percent_system": "0.18",
|
||||
"percent_iowait": "0.00",
|
||||
"percent_steal": "0.00",
|
||||
"percent_idle": "99.67",
|
||||
"type": "cpu"
|
||||
},
|
||||
{
|
||||
"device": "sda",
|
||||
"tps": "0.29",
|
||||
"kb_read_s": "7.22",
|
||||
"kb_wrtn_s": "1.25",
|
||||
"kb_read": "194341",
|
||||
"kb_wrtn": "33590",
|
||||
"type": "device"
|
||||
},
|
||||
{
|
||||
"device": "dm-0",
|
||||
"tps": "0.29",
|
||||
"kb_read_s": "5.99",
|
||||
"kb_wrtn_s": "1.17",
|
||||
"kb_read": "161361",
|
||||
"kb_wrtn": "31522",
|
||||
"type": "device"
|
||||
},
|
||||
{
|
||||
"device": "dm-1",
|
||||
"tps": "0.00",
|
||||
"kb_read_s": "0.08",
|
||||
"kb_wrtn_s": "0.00",
|
||||
"kb_read": "2204",
|
||||
"kb_wrtn": "0",
|
||||
"type": "device"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
## info
|
||||
```python
|
||||
info()
|
||||
```
|
||||
Provides parser metadata (version, author, etc.)
|
||||
|
||||
## 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.
|
||||
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
126
docs/parsers/iostat_s.md
Normal file
126
docs/parsers/iostat_s.md
Normal file
@@ -0,0 +1,126 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
|
||||
# jc.parsers.iostat_s
|
||||
jc - JSON CLI output utility `iostat` command output streaming parser
|
||||
|
||||
> This streaming parser outputs JSON Lines
|
||||
|
||||
Note: `iostat` version 11 and higher include a JSON output option
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ iostat | jc --iostat-s
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc.parsers.iostat_s
|
||||
result = jc.parsers.iostat_s.parse(iostat_command_output.splitlines()) # result is an iterable object
|
||||
for item in result:
|
||||
# do something
|
||||
|
||||
Schema:
|
||||
|
||||
{
|
||||
"type": string,
|
||||
"percent_user": float,
|
||||
"percent_nice": float,
|
||||
"percent_system": float,
|
||||
"percent_iowait": float,
|
||||
"percent_steal": float,
|
||||
"percent_idle": float,
|
||||
"device": string,
|
||||
"tps": float,
|
||||
"kb_read_s": float,
|
||||
"mb_read_s": float,
|
||||
"kb_wrtn_s": float,
|
||||
"mb_wrtn_s": float,
|
||||
"kb_read": integer,
|
||||
"mb_read": integer,
|
||||
"kb_wrtn": integer,
|
||||
"mb_wrtn": integer,
|
||||
'kb_dscd': integer,
|
||||
'mb_dscd': integer,
|
||||
"rrqm_s": float,
|
||||
"wrqm_s": float,
|
||||
"r_s": float,
|
||||
"w_s": float,
|
||||
"rmb_s": float,
|
||||
"rkb_s": float,
|
||||
"wmb_s": float,
|
||||
"wkb_s": float,
|
||||
"avgrq_sz": float,
|
||||
"avgqu_sz": float,
|
||||
"await": float,
|
||||
"r_await": float,
|
||||
"w_await": float,
|
||||
"svctm": float,
|
||||
"aqu_sz": float,
|
||||
"rareq_sz": float,
|
||||
"wareq_sz": float,
|
||||
"d_s": float,
|
||||
"dkb_s": float,
|
||||
"dmb_s": float,
|
||||
"drqm_s": float,
|
||||
"percent_drqm": float,
|
||||
"d_await": float,
|
||||
"dareq_sz": float,
|
||||
"f_s": float,
|
||||
"f_await": float,
|
||||
"kb_dscd_s": float,
|
||||
"mb_dscd_s": float,
|
||||
"percent_util": float,
|
||||
"percent_rrqm": float,
|
||||
"percent_wrqm": float,
|
||||
"_jc_meta": # This object only exists if using -qq or ignore_exceptions=True
|
||||
{
|
||||
"success": boolean, # true if successfully parsed, false if error
|
||||
"error": string, # exists if "success" is false
|
||||
"line": string # exists if "success" is false
|
||||
}
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ iostat | jc --iostat-s
|
||||
{"percent_user":0.14,"percent_nice":0.0,"percent_system":0.16,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":99.7,"type":"cpu"}
|
||||
{"device":"sda","tps":0.24,"kb_read_s":5.28,"kb_wrtn_s":1.1,"kb_read":203305,"kb_wrtn":42368,"type":"device"}
|
||||
...
|
||||
|
||||
$ iostat | jc --iostat-s -r
|
||||
{"percent_user":"0.14","percent_nice":"0.00","percent_system":"0.16","percent_iowait":"0.00","percent_steal":"0.00","percent_idle":"99.70","type":"cpu"}
|
||||
{"device":"sda","tps":"0.24","kb_read_s":"5.28","kb_wrtn_s":"1.10","kb_read":"203305","kb_wrtn":"42368","type":"device"}
|
||||
...
|
||||
|
||||
|
||||
## info
|
||||
```python
|
||||
info()
|
||||
```
|
||||
Provides parser metadata (version, author, etc.)
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False, ignore_exceptions=False)
|
||||
```
|
||||
|
||||
Main text parsing generator function. Returns an iterator object.
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (iterable) line-based text data to parse (e.g. sys.stdin or str.splitlines())
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
ignore_exceptions: (boolean) ignore parsing exceptions if True
|
||||
|
||||
Yields:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
Returns:
|
||||
|
||||
Iterator object
|
||||
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -188,4 +188,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -145,4 +145,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 0.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 0.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -117,4 +117,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, aix, freebsd
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -38,7 +38,7 @@ Examples:
|
||||
# but can be preserved with the -r argument
|
||||
occupation:"Engineer"
|
||||
|
||||
$ cat keyvalue.txt | jc --ini -p
|
||||
$ cat keyvalue.txt | jc --kv -p
|
||||
{
|
||||
"name": "John Doe",
|
||||
"address": "555 California Drive",
|
||||
|
||||
@@ -128,4 +128,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, aix, freebsd
|
||||
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -131,4 +131,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, aix, freebsd
|
||||
|
||||
Version 1.9 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.10 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
94
docs/parsers/ls_s.md
Normal file
94
docs/parsers/ls_s.md
Normal file
@@ -0,0 +1,94 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
|
||||
# jc.parsers.ls_s
|
||||
jc - JSON CLI output utility `ls` and `vdir` command output streaming parser
|
||||
|
||||
> This streaming parser outputs JSON Lines
|
||||
|
||||
Requires the `-l` option to be used on `ls`. If there are newline characters in the filename, then make sure to use the `-b` option on `ls`.
|
||||
|
||||
The `jc` `-qq` option can be used to ignore parsing errors. (e.g. filenames with newline characters, but `-b` was not used)
|
||||
|
||||
The `epoch` calculated timestamp field is naive (i.e. based on the local time of the system the parser is run on)
|
||||
|
||||
The `epoch_utc` calculated timestamp field is timezone-aware and is only available if the timezone field is UTC.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ ls | jc --ls-s
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc.parsers.ls_s
|
||||
result = jc.parsers.ls_s.parse(ls_command_output.splitlines()) # result is an iterable object
|
||||
for item in result:
|
||||
# do something
|
||||
|
||||
Schema:
|
||||
|
||||
{
|
||||
"filename": string,
|
||||
"flags": string,
|
||||
"links": integer,
|
||||
"parent": string,
|
||||
"owner": string,
|
||||
"group": string,
|
||||
"size": integer,
|
||||
"date": string,
|
||||
"epoch": integer, # naive timestamp if date field exists and can be converted
|
||||
"epoch_utc": integer, # timezone aware timestamp if date field is in UTC and can be converted
|
||||
"_jc_meta": # This object only exists if using -qq or ignore_exceptions=True
|
||||
{
|
||||
"success": boolean, # true if successfully parsed, false if error
|
||||
"error": string, # exists if "success" is false
|
||||
"line": string # exists if "success" is false
|
||||
}
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ ls -l /usr/bin | jc --ls-s
|
||||
{"filename":"2to3-","flags":"-rwxr-xr-x","links":4,"owner":"root","group":"wheel","size":925,"date":"Feb 22 2019"}
|
||||
{"filename":"2to3-2.7","link_to":"../../System/Library/Frameworks/Python.framework/Versions/2.7/bin/2to3-2.7","flags":"lrwxr-xr-x","links":1,"owner":"root","group":"wheel","size":74,"date":"May 4 2019"}
|
||||
{"filename":"AssetCacheLocatorUtil","flags":"-rwxr-xr-x","links":1,"owner":"root","group":"wheel","size":55152,"date":"May 3 2019"}
|
||||
...
|
||||
|
||||
$ ls -l /usr/bin | jc --ls-s -r
|
||||
{"filename":"2to3-","flags":"-rwxr-xr-x","links":"4","owner":"root","group":"wheel","size":"925","date":"Feb 22 2019"}
|
||||
{"filename":"2to3-2.7","link_to":"../../System/Library/Frameworks/Python.framework/Versions/2.7/bin/2to3-2.7","flags":"lrwxr-xr-x","links":"1","owner":"root","group":"wheel","size":"74","date":"May 4 2019"}
|
||||
{"filename":"AssetCacheLocatorUtil","flags":"-rwxr-xr-x","links":"1","owner":"root","group":"wheel","size":"55152","date":"May 3 2019"}
|
||||
...
|
||||
|
||||
|
||||
## info
|
||||
```python
|
||||
info()
|
||||
```
|
||||
Provides parser metadata (version, author, etc.)
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False, ignore_exceptions=False)
|
||||
```
|
||||
|
||||
Main text parsing generator function. Returns an iterator object.
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (iterable) line-based text data to parse (e.g. sys.stdin or str.splitlines())
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
ignore_exceptions: (boolean) ignore parsing exceptions if True
|
||||
|
||||
Yields:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
Returns:
|
||||
|
||||
Iterator object
|
||||
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, aix, freebsd
|
||||
|
||||
Version 0.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -293,4 +293,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -150,4 +150,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -144,4 +144,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
288
docs/parsers/lsusb.md
Normal file
288
docs/parsers/lsusb.md
Normal file
@@ -0,0 +1,288 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
|
||||
# jc.parsers.lsusb
|
||||
jc - JSON CLI output utility `lsusb` command output parser
|
||||
|
||||
Supports the `-v` option or no options.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ lsusb -v | jc --lsusb
|
||||
|
||||
or
|
||||
|
||||
$ jc lsusb -v
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc.parsers.lsusb
|
||||
result = jc.parsers.lsusb.parse(lsusb_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
Note: <item> object keynames are assigned directly from the lsusb output.
|
||||
If there are duplicate <item> names in a section, only the last one is converted.
|
||||
|
||||
[
|
||||
{
|
||||
"bus": string,
|
||||
"device": string,
|
||||
"id": string,
|
||||
"description": string,
|
||||
"device_descriptor": {
|
||||
"<item>": {
|
||||
"value": string,
|
||||
"description": string,
|
||||
"attributes": [
|
||||
string
|
||||
]
|
||||
},
|
||||
"configuration_descriptor": {
|
||||
"<item>": {
|
||||
"value": string,
|
||||
"description": string,
|
||||
"attributes": [
|
||||
string
|
||||
]
|
||||
},
|
||||
"interface_association": {
|
||||
"<item>": {
|
||||
"value": string,
|
||||
"description": string,
|
||||
"attributes": [
|
||||
string
|
||||
]
|
||||
}
|
||||
},
|
||||
"interface_descriptors": [
|
||||
{
|
||||
"<item>": {
|
||||
"value": string,
|
||||
"description": string,
|
||||
"attributes": [
|
||||
string
|
||||
]
|
||||
},
|
||||
"cdc_header": {
|
||||
"<item>": {
|
||||
"value": string,
|
||||
"description": string,
|
||||
"attributes": [
|
||||
string
|
||||
]
|
||||
}
|
||||
},
|
||||
"cdc_call_management": {
|
||||
"<item>": {
|
||||
"value": string,
|
||||
"description": string,
|
||||
"attributes": [
|
||||
string
|
||||
]
|
||||
}
|
||||
},
|
||||
"cdc_acm": {
|
||||
"<item>": {
|
||||
"value": string,
|
||||
"description": string,
|
||||
"attributes": [
|
||||
string
|
||||
]
|
||||
}
|
||||
},
|
||||
"cdc_union": {
|
||||
"<item>": {
|
||||
"value": string,
|
||||
"description": string,
|
||||
"attributes": [
|
||||
string
|
||||
]
|
||||
}
|
||||
},
|
||||
"endpoint_descriptors": [
|
||||
{
|
||||
"<item>": {
|
||||
"value": string,
|
||||
"description": string,
|
||||
"attributes": [
|
||||
string
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"hub_descriptor": {
|
||||
"<item>": {
|
||||
"value": string,
|
||||
"description": string,
|
||||
"attributes": [
|
||||
string,
|
||||
]
|
||||
},
|
||||
"hub_port_status": {
|
||||
"<item>": {
|
||||
"value": string,
|
||||
"attributes": [
|
||||
string
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"device_status": {
|
||||
"value": string,
|
||||
"description": string
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ lsusb -v | jc --lsusb -p
|
||||
[
|
||||
{
|
||||
"bus": "002",
|
||||
"device": "001",
|
||||
"id": "1d6b:0001",
|
||||
"description": "Linux Foundation 1.1 root hub",
|
||||
"device_descriptor": {
|
||||
"bLength": {
|
||||
"value": "18"
|
||||
},
|
||||
"bDescriptorType": {
|
||||
"value": "1"
|
||||
},
|
||||
"bcdUSB": {
|
||||
"value": "1.10"
|
||||
},
|
||||
...
|
||||
"bNumConfigurations": {
|
||||
"value": "1"
|
||||
},
|
||||
"configuration_descriptor": {
|
||||
"bLength": {
|
||||
"value": "9"
|
||||
},
|
||||
...
|
||||
"iConfiguration": {
|
||||
"value": "0"
|
||||
},
|
||||
"bmAttributes": {
|
||||
"value": "0xe0",
|
||||
"attributes": [
|
||||
"Self Powered",
|
||||
"Remote Wakeup"
|
||||
]
|
||||
},
|
||||
"MaxPower": {
|
||||
"description": "0mA"
|
||||
},
|
||||
"interface_descriptors": [
|
||||
{
|
||||
"bLength": {
|
||||
"value": "9"
|
||||
},
|
||||
...
|
||||
"bInterfaceProtocol": {
|
||||
"value": "0",
|
||||
"description": "Full speed (or root) hub"
|
||||
},
|
||||
"iInterface": {
|
||||
"value": "0"
|
||||
},
|
||||
"endpoint_descriptors": [
|
||||
{
|
||||
"bLength": {
|
||||
"value": "7"
|
||||
},
|
||||
...
|
||||
"bmAttributes": {
|
||||
"value": "3",
|
||||
"attributes": [
|
||||
"Transfer Type Interrupt",
|
||||
"Synch Type None",
|
||||
"Usage Type Data"
|
||||
]
|
||||
},
|
||||
"wMaxPacketSize": {
|
||||
"value": "0x0002",
|
||||
"description": "1x 2 bytes"
|
||||
},
|
||||
"bInterval": {
|
||||
"value": "255"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"hub_descriptor": {
|
||||
"bLength": {
|
||||
"value": "9"
|
||||
},
|
||||
...
|
||||
"wHubCharacteristic": {
|
||||
"value": "0x000a",
|
||||
"attributes": [
|
||||
"No power switching (usb 1.0)",
|
||||
"Per-port overcurrent protection"
|
||||
]
|
||||
},
|
||||
...
|
||||
"hub_port_status": {
|
||||
"Port 1": {
|
||||
"value": "0000.0103",
|
||||
"attributes": [
|
||||
"power",
|
||||
"enable",
|
||||
"connect"
|
||||
]
|
||||
},
|
||||
"Port 2": {
|
||||
"value": "0000.0103",
|
||||
"attributes": [
|
||||
"power",
|
||||
"enable",
|
||||
"connect"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"device_status": {
|
||||
"value": "0x0001",
|
||||
"description": "Self Powered"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
## info
|
||||
```python
|
||||
info()
|
||||
```
|
||||
Provides parser metadata (version, author, etc.)
|
||||
|
||||
## 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.
|
||||
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -100,4 +100,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -379,4 +379,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.10 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.12 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -231,4 +231,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, freebsd
|
||||
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -119,4 +119,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, aix, freebsd
|
||||
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -181,4 +181,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
101
docs/parsers/ping_s.md
Normal file
101
docs/parsers/ping_s.md
Normal file
@@ -0,0 +1,101 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
|
||||
# jc.parsers.ping_s
|
||||
jc - JSON CLI output utility `ping` command output streaming parser
|
||||
|
||||
> This streaming parser outputs JSON Lines
|
||||
|
||||
Supports `ping` and `ping6` output.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ ping | jc --ping-s
|
||||
|
||||
> Note: When piping `jc` converted `ping` output to other processes it may appear the output is hanging due to the OS pipe buffers. This is because `ping` output is too small to quickly fill up the buffer. Use the `-u` option to unbuffer the `jc` output if you would like immediate output. See the [readme](https://github.com/kellyjonbrazil/jc/tree/master#unbuffering-output) for more information.
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc.parsers.ping_s
|
||||
result = jc.parsers.ping_s.parse(ping_command_output.splitlines()) # result is an iterable object
|
||||
for item in result:
|
||||
# do something
|
||||
|
||||
Schema:
|
||||
|
||||
{
|
||||
"type": string, # 'reply', 'timeout', 'summary', etc. See `_error_type.type_map` for all options.
|
||||
"source_ip": string,
|
||||
"destination_ip": string,
|
||||
"sent_bytes": integer,
|
||||
"pattern": string, # (null if not set)
|
||||
"destination": string,
|
||||
"timestamp": float,
|
||||
"response_bytes": integer,
|
||||
"response_ip": string,
|
||||
"icmp_seq": integer,
|
||||
"ttl": integer,
|
||||
"time_ms": float,
|
||||
"duplicate": boolean,
|
||||
"packets_transmitted": integer,
|
||||
"packets_received": integer,
|
||||
"packet_loss_percent": float,
|
||||
"duplicates": integer,
|
||||
"round_trip_ms_min": float,
|
||||
"round_trip_ms_avg": float,
|
||||
"round_trip_ms_max": float,
|
||||
"round_trip_ms_stddev": float,
|
||||
"_jc_meta": # This object only exists if using -qq or ignore_exceptions=True
|
||||
{
|
||||
"success": boolean, # true if successfully parsed, false if error
|
||||
"error": string, # exists if "success" is false
|
||||
"line": string # exists if "success" is false
|
||||
}
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ ping 1.1.1.1 | jc --ping-s
|
||||
{"type":"reply","destination_ip":"1.1.1.1","sent_bytes":56,"pattern":null,"response_bytes":64,"response_ip":"1.1.1.1","icmp_seq":0,"ttl":56,"time_ms":23.703}
|
||||
{"type":"reply","destination_ip":"1.1.1.1","sent_bytes":56,"pattern":null,"response_bytes":64,"response_ip":"1.1.1.1","icmp_seq":1,"ttl":56,"time_ms":22.862}
|
||||
{"type":"reply","destination_ip":"1.1.1.1","sent_bytes":56,"pattern":null,"response_bytes":64,"response_ip":"1.1.1.1","icmp_seq":2,"ttl":56,"time_ms":22.82}
|
||||
...
|
||||
|
||||
$ ping 1.1.1.1 | jc --ping-s -r
|
||||
{"type":"reply","destination_ip":"1.1.1.1","sent_bytes":"56","pattern":null,"response_bytes":"64","response_ip":"1.1.1.1","icmp_seq":"0","ttl":"56","time_ms":"23.054"}
|
||||
{"type":"reply","destination_ip":"1.1.1.1","sent_bytes":"56","pattern":null,"response_bytes":"64","response_ip":"1.1.1.1","icmp_seq":"1","ttl":"56","time_ms":"24.739"}
|
||||
{"type":"reply","destination_ip":"1.1.1.1","sent_bytes":"56","pattern":null,"response_bytes":"64","response_ip":"1.1.1.1","icmp_seq":"2","ttl":"56","time_ms":"23.232"}
|
||||
...
|
||||
|
||||
|
||||
## info
|
||||
```python
|
||||
info()
|
||||
```
|
||||
Provides parser metadata (version, author, etc.)
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False, ignore_exceptions=False)
|
||||
```
|
||||
|
||||
Main text parsing generator function. Returns an iterator object.
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (iterable) line-based text data to parse (e.g. sys.stdin or str.splitlines())
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
ignore_exceptions: (boolean) ignore parsing exceptions if True
|
||||
|
||||
Yields:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
Returns:
|
||||
|
||||
Iterator object
|
||||
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 0.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -72,4 +72,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -90,4 +90,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -231,4 +231,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, aix, freebsd
|
||||
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -25,7 +25,7 @@ Schema:
|
||||
"genmask": string,
|
||||
"flags": string,
|
||||
"flags_pretty": [
|
||||
string,
|
||||
string
|
||||
]
|
||||
"metric": integer,
|
||||
"ref": integer,
|
||||
@@ -76,7 +76,6 @@ Examples:
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
$ route -ee | jc --route -p -r
|
||||
[
|
||||
{
|
||||
@@ -108,7 +107,6 @@ Examples:
|
||||
]
|
||||
|
||||
|
||||
|
||||
## info
|
||||
```python
|
||||
info()
|
||||
@@ -135,4 +133,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -181,4 +181,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
228
docs/parsers/sfdisk.md
Normal file
228
docs/parsers/sfdisk.md
Normal file
@@ -0,0 +1,228 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
|
||||
# jc.parsers.sfdisk
|
||||
jc - JSON CLI output utility `sfdisk` command output parser
|
||||
|
||||
Supports the following `sfdisk` options:
|
||||
- `-l`
|
||||
- `-F`
|
||||
- `-d` (deprecated - only for older versions of util-linux)
|
||||
- `-uM` (deprecated - only for older versions of util-linux)
|
||||
- `-uC` (deprecated - only for older versions of util-linux)
|
||||
- `-uS` (deprecated - only for older versions of util-linux)
|
||||
- `-uB` (deprecated - only for older versions of util-linux)
|
||||
|
||||
Usage (cli):
|
||||
|
||||
# sfdisk -l | jc --sfdisk
|
||||
|
||||
or
|
||||
|
||||
# jc sfdisk -l
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc.parsers.sfdisk
|
||||
result = jc.parsers.sfdisk.parse(sfdisk_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"disk": string,
|
||||
"disk_size": string,
|
||||
"free_disk_size": string,
|
||||
"bytes": integer,
|
||||
"free_bytes": integer,
|
||||
"sectors": integer,
|
||||
"free_sectors": integer,
|
||||
"cylinders": integer,
|
||||
"heads": integer,
|
||||
"sectors_per_track": integer,
|
||||
"units": string,
|
||||
"logical_sector_size": integer,
|
||||
"physical_sector_size": integer,
|
||||
"min_io_size": integer,
|
||||
"optimal_io_size": integer,
|
||||
"disk_label_type": string,
|
||||
"disk_identifier": string,
|
||||
"disk_model": string,
|
||||
"partitions": [
|
||||
{
|
||||
"device": string,
|
||||
"boot": boolean,
|
||||
"start": integer,
|
||||
"end": integer,
|
||||
"size": string, # Note: will be integer when using deprecated -d sfdisk option
|
||||
"cyls": integer,
|
||||
"mib": integer,
|
||||
"blocks": integer,
|
||||
"sectors": integer,
|
||||
"id": string,
|
||||
"system": string,
|
||||
"type": string
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
# sfdisk -l | jc --sfdisk -p
|
||||
[
|
||||
{
|
||||
"disk": "/dev/sda",
|
||||
"cylinders": 2610,
|
||||
"heads": 255,
|
||||
"sectors_per_track": 63,
|
||||
"units": "cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0",
|
||||
"partitions": [
|
||||
{
|
||||
"device": "/dev/sda1",
|
||||
"boot": true,
|
||||
"start": 0,
|
||||
"end": 130,
|
||||
"cyls": 131,
|
||||
"blocks": 1048576,
|
||||
"id": "83",
|
||||
"system": "Linux"
|
||||
},
|
||||
{
|
||||
"device": "/dev/sda2",
|
||||
"boot": false,
|
||||
"start": 130,
|
||||
"end": 2610,
|
||||
"cyls": 2481,
|
||||
"blocks": 19921920,
|
||||
"id": "8e",
|
||||
"system": "Linux LVM"
|
||||
},
|
||||
{
|
||||
"device": "/dev/sda3",
|
||||
"boot": false,
|
||||
"start": 0,
|
||||
"end": null,
|
||||
"cyls": 0,
|
||||
"blocks": 0,
|
||||
"id": "0",
|
||||
"system": "Empty"
|
||||
},
|
||||
{
|
||||
"device": "/dev/sda4",
|
||||
"boot": false,
|
||||
"start": 0,
|
||||
"end": null,
|
||||
"cyls": 0,
|
||||
"blocks": 0,
|
||||
"id": "0",
|
||||
"system": "Empty"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"disk": "/dev/mapper/centos-root",
|
||||
"cylinders": 2218,
|
||||
"heads": 255,
|
||||
"sectors_per_track": 63
|
||||
},
|
||||
{
|
||||
"disk": "/dev/mapper/centos-swap",
|
||||
"cylinders": 261,
|
||||
"heads": 255,
|
||||
"sectors_per_track": 63
|
||||
}
|
||||
]
|
||||
|
||||
# sfdisk -l | jc --sfdisk -p -r
|
||||
[
|
||||
{
|
||||
"disk": "/dev/sda",
|
||||
"cylinders": "2610",
|
||||
"heads": "255",
|
||||
"sectors_per_track": "63",
|
||||
"units": "cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0",
|
||||
"partitions": [
|
||||
{
|
||||
"device": "/dev/sda1",
|
||||
"boot": "*",
|
||||
"start": "0+",
|
||||
"end": "130-",
|
||||
"cyls": "131-",
|
||||
"blocks": "1048576",
|
||||
"id": "83",
|
||||
"system": "Linux"
|
||||
},
|
||||
{
|
||||
"device": "/dev/sda2",
|
||||
"boot": null,
|
||||
"start": "130+",
|
||||
"end": "2610-",
|
||||
"cyls": "2481-",
|
||||
"blocks": "19921920",
|
||||
"id": "8e",
|
||||
"system": "Linux LVM"
|
||||
},
|
||||
{
|
||||
"device": "/dev/sda3",
|
||||
"boot": null,
|
||||
"start": "0",
|
||||
"end": "-",
|
||||
"cyls": "0",
|
||||
"blocks": "0",
|
||||
"id": "0",
|
||||
"system": "Empty"
|
||||
},
|
||||
{
|
||||
"device": "/dev/sda4",
|
||||
"boot": null,
|
||||
"start": "0",
|
||||
"end": "-",
|
||||
"cyls": "0",
|
||||
"blocks": "0",
|
||||
"id": "0",
|
||||
"system": "Empty"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"disk": "/dev/mapper/centos-root",
|
||||
"cylinders": "2218",
|
||||
"heads": "255",
|
||||
"sectors_per_track": "63"
|
||||
},
|
||||
{
|
||||
"disk": "/dev/mapper/centos-swap",
|
||||
"cylinders": "261",
|
||||
"heads": "255",
|
||||
"sectors_per_track": "63"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
## info
|
||||
```python
|
||||
info()
|
||||
```
|
||||
Provides parser metadata (version, author, etc.)
|
||||
|
||||
## 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.
|
||||
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -126,4 +126,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, aix, freebsd
|
||||
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -303,4 +303,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -193,4 +193,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.10 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -79,4 +79,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -83,4 +83,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -100,4 +100,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -75,4 +75,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -71,4 +71,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -229,4 +229,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: win32
|
||||
|
||||
Version 1.0 by Jon Smith (jon@rebelliondefense.com)
|
||||
Version 1.1 by Jon Smith (jon@rebelliondefense.com)
|
||||
|
||||
@@ -148,4 +148,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, aix, freebsd
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -88,4 +88,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -156,4 +156,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -142,4 +142,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -222,4 +222,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -155,4 +155,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -72,4 +72,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -219,4 +219,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -90,4 +90,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, aix, freebsd
|
||||
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
149
docs/parsers/vmstat.md
Normal file
149
docs/parsers/vmstat.md
Normal file
@@ -0,0 +1,149 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
|
||||
# jc.parsers.vmstat
|
||||
jc - JSON CLI output utility `vmstat` command output parser
|
||||
|
||||
Options supported: `-a`, `-w`, `-d`, `-t`
|
||||
|
||||
The `epoch` calculated timestamp field is naive (i.e. based on the local time of the system the parser is run on)
|
||||
|
||||
The `epoch_utc` calculated timestamp field is timezone-aware and is only available if the timezone field is UTC.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ vmstat | jc --vmstat
|
||||
|
||||
or
|
||||
|
||||
$ jc vmstat
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc.parsers.vmstat
|
||||
result = jc.parsers.vmstat.parse(vmstat_command_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"runnable_procs": integer,
|
||||
"uninterruptible_sleeping_procs": integer,
|
||||
"virtual_mem_used": integer,
|
||||
"free_mem": integer,
|
||||
"buffer_mem": integer,
|
||||
"cache_mem": integer,
|
||||
"inactive_mem": integer,
|
||||
"active_mem": integer,
|
||||
"swap_in": integer,
|
||||
"swap_out": integer,
|
||||
"blocks_in": integer,
|
||||
"blocks_out": integer,
|
||||
"interrupts": integer,
|
||||
"context_switches": integer,
|
||||
"user_time": integer,
|
||||
"system_time": integer,
|
||||
"idle_time": integer,
|
||||
"io_wait_time": integer,
|
||||
"stolen_time": integer,
|
||||
"disk": string,
|
||||
"total_reads": integer,
|
||||
"merged_reads": integer,
|
||||
"sectors_read": integer,
|
||||
"reading_ms": integer,
|
||||
"total_writes": integer,
|
||||
"merged_writes": integer,
|
||||
"sectors_written": integer,
|
||||
"writing_ms": integer,
|
||||
"current_io": integer,
|
||||
"io_seconds": integer,
|
||||
"timestamp": string,
|
||||
"timezone": string,
|
||||
"epoch": integer, # naive timestamp if -t flag is used
|
||||
"epoch_utc": integer # aware timestamp if -t flag is used and UTC TZ
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ vmstat | jc --vmstat -p
|
||||
[
|
||||
{
|
||||
"runnable_procs": 2,
|
||||
"uninterruptible_sleeping_procs": 0,
|
||||
"virtual_mem_used": 0,
|
||||
"free_mem": 2794468,
|
||||
"buffer_mem": 2108,
|
||||
"cache_mem": 741208,
|
||||
"inactive_mem": null,
|
||||
"active_mem": null,
|
||||
"swap_in": 0,
|
||||
"swap_out": 0,
|
||||
"blocks_in": 1,
|
||||
"blocks_out": 3,
|
||||
"interrupts": 29,
|
||||
"context_switches": 57,
|
||||
"user_time": 0,
|
||||
"system_time": 0,
|
||||
"idle_time": 99,
|
||||
"io_wait_time": 0,
|
||||
"stolen_time": 0,
|
||||
"timestamp": null,
|
||||
"timezone": null
|
||||
}
|
||||
]
|
||||
|
||||
$ vmstat | jc --vmstat -p -r
|
||||
[
|
||||
{
|
||||
"runnable_procs": "2",
|
||||
"uninterruptible_sleeping_procs": "0",
|
||||
"virtual_mem_used": "0",
|
||||
"free_mem": "2794468",
|
||||
"buffer_mem": "2108",
|
||||
"cache_mem": "741208",
|
||||
"inactive_mem": null,
|
||||
"active_mem": null,
|
||||
"swap_in": "0",
|
||||
"swap_out": "0",
|
||||
"blocks_in": "1",
|
||||
"blocks_out": "3",
|
||||
"interrupts": "29",
|
||||
"context_switches": "57",
|
||||
"user_time": "0",
|
||||
"system_time": "0",
|
||||
"idle_time": "99",
|
||||
"io_wait_time": "0",
|
||||
"stolen_time": "0",
|
||||
"timestamp": null,
|
||||
"timezone": null
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
## info
|
||||
```python
|
||||
info()
|
||||
```
|
||||
Provides parser metadata (version, author, etc.)
|
||||
|
||||
## 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.
|
||||
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
114
docs/parsers/vmstat_s.md
Normal file
114
docs/parsers/vmstat_s.md
Normal file
@@ -0,0 +1,114 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
|
||||
# jc.parsers.vmstat_s
|
||||
jc - JSON CLI output utility `vmstat` command output streaming parser
|
||||
|
||||
> This streaming parser outputs JSON Lines
|
||||
|
||||
Options supported: `-a`, `-w`, `-d`, `-t`
|
||||
|
||||
The `epoch` calculated timestamp field is naive (i.e. based on the local time of the system the parser is run on)
|
||||
|
||||
The `epoch_utc` calculated timestamp field is timezone-aware and is only available if the timezone field is UTC.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ vmstat | jc --vmstat-s
|
||||
|
||||
> Note: When piping `jc` converted `vmstat` output to other processes it may appear the output is hanging due to the OS pipe buffers. This is because `vmstat` output is too small to quickly fill up the buffer. Use the `-u` option to unbuffer the `jc` output if you would like immediate output. See the [readme](https://github.com/kellyjonbrazil/jc/tree/master#unbuffering-output) for more information.
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc.parsers.vmstat_s
|
||||
result = jc.parsers.vmstat_s.parse(vmstat_command_output.splitlines()) # result is an iterable object
|
||||
for item in result:
|
||||
# do something
|
||||
|
||||
Schema:
|
||||
|
||||
{
|
||||
"runnable_procs": integer,
|
||||
"uninterruptible_sleeping_procs": integer,
|
||||
"virtual_mem_used": integer,
|
||||
"free_mem": integer,
|
||||
"buffer_mem": integer,
|
||||
"cache_mem": integer,
|
||||
"inactive_mem": integer,
|
||||
"active_mem": integer,
|
||||
"swap_in": integer,
|
||||
"swap_out": integer,
|
||||
"blocks_in": integer,
|
||||
"blocks_out": integer,
|
||||
"interrupts": integer,
|
||||
"context_switches": integer,
|
||||
"user_time": integer,
|
||||
"system_time": integer,
|
||||
"idle_time": integer,
|
||||
"io_wait_time": integer,
|
||||
"stolen_time": integer,
|
||||
"disk": string,
|
||||
"total_reads": integer,
|
||||
"merged_reads": integer,
|
||||
"sectors_read": integer,
|
||||
"reading_ms": integer,
|
||||
"total_writes": integer,
|
||||
"merged_writes": integer,
|
||||
"sectors_written": integer,
|
||||
"writing_ms": integer,
|
||||
"current_io": integer,
|
||||
"io_seconds": integer,
|
||||
"timestamp": string,
|
||||
"timezone": string,
|
||||
"epoch": integer, # naive timestamp if -t flag is used
|
||||
"epoch_utc": integer # aware timestamp if -t flag is used and UTC TZ
|
||||
"_jc_meta": # This object only exists if using -qq or ignore_exceptions=True
|
||||
{
|
||||
"success": boolean, # true if successfully parsed, false if error
|
||||
"error": string, # exists if "success" is false
|
||||
"line": string # exists if "success" is false
|
||||
}
|
||||
}
|
||||
|
||||
Examples:
|
||||
|
||||
$ vmstat | jc --vmstat-s
|
||||
{"runnable_procs":2,"uninterruptible_sleeping_procs":0,"virtual_mem_used":0,"free_mem":2794468,"buffer_mem":2108,"cache_mem":741208,"inactive_mem":null,"active_mem":null,"swap_in":0,"swap_out":0,"blocks_in":1,"blocks_out":3,"interrupts":29,"context_switches":57,"user_time":0,"system_time":0,"idle_time":99,"io_wait_time":0,"stolen_time":0,"timestamp":null,"timezone":null}
|
||||
...
|
||||
|
||||
$ vmstat | jc --vmstat-s -r
|
||||
{"runnable_procs":"2","uninterruptible_sleeping_procs":"0","virtual_mem_used":"0","free_mem":"2794468","buffer_mem":"2108","cache_mem":"741208","inactive_mem":null,"active_mem":null,"swap_in":"0","swap_out":"0","blocks_in":"1","blocks_out":"3","interrupts":"29","context_switches":"57","user_time":"0","system_time":"0","idle_time":"99","io_wait_time":"0","stolen_time":"0","timestamp":null,"timezone":null}
|
||||
...
|
||||
|
||||
|
||||
## info
|
||||
```python
|
||||
info()
|
||||
```
|
||||
Provides parser metadata (version, author, etc.)
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False, ignore_exceptions=False)
|
||||
```
|
||||
|
||||
Main text parsing generator function. Returns an iterator object.
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (iterable) line-based text data to parse (e.g. sys.stdin or str.splitlines())
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
ignore_exceptions: (boolean) ignore parsing exceptions if True
|
||||
|
||||
Yields:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
Returns:
|
||||
|
||||
Iterator object
|
||||
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 0.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
@@ -128,4 +128,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, aix, freebsd
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -79,4 +79,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, aix, freebsd
|
||||
|
||||
Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -157,4 +157,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, aix, freebsd
|
||||
|
||||
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -95,4 +95,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -109,4 +109,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
106
docs/parsers/zipinfo.md
Normal file
106
docs/parsers/zipinfo.md
Normal file
@@ -0,0 +1,106 @@
|
||||
[Home](https://kellyjonbrazil.github.io/jc/)
|
||||
|
||||
# jc.parsers.zipinfo
|
||||
jc - JSON CLI output utility `zipinfo` command output parser
|
||||
|
||||
Options supported:
|
||||
- none
|
||||
|
||||
Note: The default listing format.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ zipinfo <archive> | jc --zipinfo
|
||||
|
||||
or
|
||||
|
||||
$ jc zipinfo
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc.parsers.zipinfo
|
||||
result = jc.parsers.zipinfo.parse(zipinfo_command_output)
|
||||
|
||||
Schema:
|
||||
[
|
||||
{
|
||||
"archive": string,
|
||||
"size": integer,
|
||||
"size_unit": string,
|
||||
"number_entries": integer,
|
||||
"number_files": integer,
|
||||
"bytes_uncompressed": integer,
|
||||
"bytes_compressed": integer,
|
||||
"percent_compressed": float,
|
||||
"files": [
|
||||
{
|
||||
"flags": string,
|
||||
"zipversion": string,
|
||||
"zipunder": string
|
||||
"filesize": integer,
|
||||
"type": string,
|
||||
"method": string,
|
||||
"date": string,
|
||||
"time": string,
|
||||
"filename": string
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ zipinfo log4j-core-2.16.0.jar | jc --zipinfo -p
|
||||
|
||||
[
|
||||
{
|
||||
"archive": "log4j-core-2.16.0.jar",
|
||||
"size": 1789565,
|
||||
"size_unit": "bytes",
|
||||
"number_entries": 1218,
|
||||
"number_files": 1218,
|
||||
"bytes_uncompressed": 3974141,
|
||||
"bytes_compressed": 1515455,
|
||||
"percent_compressed": 61.9,
|
||||
"files": [
|
||||
{
|
||||
"flags": "-rw-r--r--",
|
||||
"zipversion": "2.0",
|
||||
"zipunder": "unx",
|
||||
"filesize": 19810,
|
||||
"type": "bl",
|
||||
"method": "defN",
|
||||
"date": "21-Dec-12",
|
||||
"time": "23:35",
|
||||
"filename": "META-INF/MANIFEST.MF"
|
||||
},
|
||||
...
|
||||
|
||||
|
||||
## info
|
||||
```python
|
||||
info()
|
||||
```
|
||||
Provides parser metadata (version, author, etc.)
|
||||
|
||||
## 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.
|
||||
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin
|
||||
|
||||
Version 0.01 by Matt J (https://github.com/listuser)
|
||||
@@ -59,26 +59,13 @@ Module Example:
|
||||
|
||||
>>> import jc.parsers.dig
|
||||
>>>
|
||||
>>> data = '''; <<>> DiG 9.10.6 <<>> example.com
|
||||
... ;; global options: +cmd
|
||||
... ;; Got answer:
|
||||
... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64612
|
||||
... ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
|
||||
...
|
||||
... ;; OPT PSEUDOSECTION:
|
||||
... ; EDNS: version: 0, flags:; udp: 4096
|
||||
... ;; QUESTION SECTION:
|
||||
... ;example.com. IN A
|
||||
...
|
||||
... ;; ANSWER SECTION:
|
||||
... example.com. 29658 IN A 93.184.216.34
|
||||
...
|
||||
... ;; Query time: 52 msec
|
||||
... ;; SERVER: 2600:1700:bab0:d40::1#53(2600:1700:bab0:d40::1)
|
||||
... ;; WHEN: Fri Apr 16 16:13:00 PDT 2021
|
||||
... ;; MSG SIZE rcvd: 56'''
|
||||
>>> import subprocess
|
||||
>>> import jc.parsers.dig
|
||||
>>>
|
||||
>>> jc.parsers.dig.parse(data)
|
||||
>>> cmd_output = subprocess.check_output(['dig', 'example.com'], text=True)
|
||||
>>> data = jc.parsers.dig.parse(cmd_output)
|
||||
>>>
|
||||
>>> data
|
||||
[{'id': 64612, 'opcode': 'QUERY', 'status': 'NOERROR', 'flags': ['qr', 'rd', 'ra'], 'query_num': 1, 'answer_num':
|
||||
1, 'authority_num': 0, 'additional_num': 1, 'opt_pseudosection': {'edns': {'version': 0, 'flags': [], 'udp':
|
||||
4096}}, 'question': {'name': 'example.com.', 'class': 'IN', 'type': 'A'}, 'answer': [{'name': 'example.com.',
|
||||
|
||||
@@ -4,14 +4,16 @@ jc - JSON CLI output utility utils
|
||||
|
||||
## warning_message
|
||||
```python
|
||||
warning_message(message)
|
||||
warning_message(message_lines)
|
||||
```
|
||||
|
||||
Prints a warning message for non-fatal issues
|
||||
Prints warning message for non-fatal issues. The first line is prepended with
|
||||
'jc: Warning - ' and subsequent lines are indented. Wraps text as needed based
|
||||
on the terminal width.
|
||||
|
||||
Parameters:
|
||||
|
||||
message: (string) text of message
|
||||
message: (list) list of string lines
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -20,14 +22,16 @@ Returns:
|
||||
|
||||
## error_message
|
||||
```python
|
||||
error_message(message)
|
||||
error_message(message_lines)
|
||||
```
|
||||
|
||||
Prints an error message for fatal issues
|
||||
Prints an error message for fatal issues. The first line is prepended with
|
||||
'jc: Error - ' and subsequent lines are indented. Wraps text as needed based
|
||||
on the terminal width.
|
||||
|
||||
Parameters:
|
||||
|
||||
message: (string) text of message
|
||||
message: (list) list of string lines
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -36,7 +40,7 @@ Returns:
|
||||
|
||||
## compatibility
|
||||
```python
|
||||
compatibility(mod_name, compatible)
|
||||
compatibility(mod_name, compatible, quiet=False)
|
||||
```
|
||||
Checks for the parser's compatibility with the running OS platform.
|
||||
|
||||
@@ -48,6 +52,8 @@ Parameters:
|
||||
compatible options:
|
||||
linux, darwin, cygwin, win32, aix, freebsd
|
||||
|
||||
quiet: (bool) supress compatibility message if True
|
||||
|
||||
Returns:
|
||||
|
||||
None - just prints output to STDERR
|
||||
@@ -117,6 +123,38 @@ Returns:
|
||||
True/False False unless a 'truthy' number or string is found ('y', 'yes', 'true', '1', 1, -1, etc.)
|
||||
|
||||
|
||||
## stream_success
|
||||
```python
|
||||
stream_success(output_line, ignore_exceptions)
|
||||
```
|
||||
Add `_jc_meta` object to output line if `ignore_exceptions=True`
|
||||
|
||||
## stream_error
|
||||
```python
|
||||
stream_error(e, ignore_exceptions, line)
|
||||
```
|
||||
Reraise the stream exception with annotation or print an error `_jc_meta`
|
||||
field if `ignore_exceptions=True`
|
||||
|
||||
|
||||
## input_type_check
|
||||
```python
|
||||
input_type_check(data)
|
||||
```
|
||||
Ensure input data is a string
|
||||
|
||||
## streaming_input_type_check
|
||||
```python
|
||||
streaming_input_type_check(data)
|
||||
```
|
||||
Ensure input data is an iterable, but not a string or bytes
|
||||
|
||||
## streaming_line_input_type_check
|
||||
```python
|
||||
streaming_line_input_type_check(line)
|
||||
```
|
||||
Ensure each line is a string
|
||||
|
||||
## timestamp
|
||||
```python
|
||||
timestamp(datetime_string)
|
||||
@@ -131,7 +169,7 @@ Parameters:
|
||||
Attributes:
|
||||
|
||||
string (str) the input datetime string
|
||||
format (int) the format rule that was used to decode the datetime string
|
||||
format (int) the format rule that was used to decode the datetime string. None if conversion fails
|
||||
naive (int) timestamp based on locally configured timezone. None if conversion fails
|
||||
utc (int) aware timestamp only if UTC timezone detected in datetime string. None if conversion fails
|
||||
|
||||
|
||||
@@ -57,26 +57,13 @@ Module Example:
|
||||
|
||||
>>> import jc.parsers.dig
|
||||
>>>
|
||||
>>> data = '''; <<>> DiG 9.10.6 <<>> example.com
|
||||
... ;; global options: +cmd
|
||||
... ;; Got answer:
|
||||
... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64612
|
||||
... ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
|
||||
...
|
||||
... ;; OPT PSEUDOSECTION:
|
||||
... ; EDNS: version: 0, flags:; udp: 4096
|
||||
... ;; QUESTION SECTION:
|
||||
... ;example.com. IN A
|
||||
...
|
||||
... ;; ANSWER SECTION:
|
||||
... example.com. 29658 IN A 93.184.216.34
|
||||
...
|
||||
... ;; Query time: 52 msec
|
||||
... ;; SERVER: 2600:1700:bab0:d40::1#53(2600:1700:bab0:d40::1)
|
||||
... ;; WHEN: Fri Apr 16 16:13:00 PDT 2021
|
||||
... ;; MSG SIZE rcvd: 56'''
|
||||
>>> import subprocess
|
||||
>>> import jc.parsers.dig
|
||||
>>>
|
||||
>>> jc.parsers.dig.parse(data)
|
||||
>>> cmd_output = subprocess.check_output(['dig', 'example.com'], text=True)
|
||||
>>> data = jc.parsers.dig.parse(cmd_output)
|
||||
>>>
|
||||
>>> data
|
||||
[{'id': 64612, 'opcode': 'QUERY', 'status': 'NOERROR', 'flags': ['qr', 'rd', 'ra'], 'query_num': 1, 'answer_num':
|
||||
1, 'authority_num': 0, 'additional_num': 1, 'opt_pseudosection': {'edns': {'version': 0, 'flags': [], 'udp':
|
||||
4096}}, 'question': {'name': 'example.com.', 'class': 'IN', 'type': 'A'}, 'answer': [{'name': 'example.com.',
|
||||
@@ -86,4 +73,4 @@ Module Example:
|
||||
"""
|
||||
|
||||
name = 'jc'
|
||||
__version__ = '1.15.5'
|
||||
__version__ = '1.17.5'
|
||||
|
||||
208
jc/cli.py
208
jc/cli.py
@@ -6,14 +6,14 @@ import sys
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import shlex
|
||||
import importlib
|
||||
import textwrap
|
||||
import signal
|
||||
import shlex
|
||||
import subprocess
|
||||
import json
|
||||
import jc
|
||||
import jc.appdirs as appdirs
|
||||
from jc import appdirs
|
||||
import jc.utils
|
||||
import jc.tracebackplus
|
||||
from jc.exceptions import LibraryNotInstalled, ParseError
|
||||
@@ -26,9 +26,9 @@ try:
|
||||
from pygments.token import (Name, Number, String, Keyword)
|
||||
from pygments.lexers import JsonLexer
|
||||
from pygments.formatters import Terminal256Formatter
|
||||
pygments_installed = True
|
||||
PYGMENTS_INSTALLED = True
|
||||
except Exception:
|
||||
pygments_installed = False
|
||||
PYGMENTS_INSTALLED = False
|
||||
|
||||
|
||||
class info():
|
||||
@@ -53,6 +53,7 @@ parsers = [
|
||||
'crontab',
|
||||
'crontab-u',
|
||||
'csv',
|
||||
'csv-s',
|
||||
'date',
|
||||
'df',
|
||||
'dig',
|
||||
@@ -75,25 +76,31 @@ parsers = [
|
||||
'id',
|
||||
'ifconfig',
|
||||
'ini',
|
||||
'iostat',
|
||||
'iostat-s',
|
||||
'iptables',
|
||||
'iw-scan',
|
||||
'jobs',
|
||||
'kv',
|
||||
'last',
|
||||
'ls',
|
||||
'ls-s',
|
||||
'lsblk',
|
||||
'lsmod',
|
||||
'lsof',
|
||||
'lsusb',
|
||||
'mount',
|
||||
'netstat',
|
||||
'ntpq',
|
||||
'passwd',
|
||||
'ping',
|
||||
'ping-s',
|
||||
'pip-list',
|
||||
'pip-show',
|
||||
'ps',
|
||||
'route',
|
||||
'rpm-qi',
|
||||
'sfdisk',
|
||||
'shadow',
|
||||
'ss',
|
||||
'stat',
|
||||
@@ -112,11 +119,14 @@ parsers = [
|
||||
'uname',
|
||||
'upower',
|
||||
'uptime',
|
||||
'vmstat',
|
||||
'vmstat-s',
|
||||
'w',
|
||||
'wc',
|
||||
'who',
|
||||
'xml',
|
||||
'yaml'
|
||||
'yaml',
|
||||
'zipinfo'
|
||||
]
|
||||
|
||||
JC_ERROR_EXIT = 100
|
||||
@@ -130,7 +140,7 @@ local_parsers_dir = os.path.join(data_dir, 'jcparsers')
|
||||
if os.path.isdir(local_parsers_dir):
|
||||
sys.path.append(data_dir)
|
||||
for name in os.listdir(local_parsers_dir):
|
||||
if re.match(r'\w+\.py', name) and os.path.isfile(os.path.join(local_parsers_dir, name)):
|
||||
if re.match(r'\w+\.py$', name) and os.path.isfile(os.path.join(local_parsers_dir, name)):
|
||||
plugin_name = name[0:-3]
|
||||
local_parsers.append(plugin_name)
|
||||
if plugin_name not in parsers:
|
||||
@@ -139,7 +149,7 @@ if os.path.isdir(local_parsers_dir):
|
||||
|
||||
# We only support 2.3.0+, pygments changed color names in 2.4.0.
|
||||
# startswith is sufficient and avoids potential exceptions from split and int.
|
||||
if pygments_installed:
|
||||
if PYGMENTS_INSTALLED:
|
||||
if pygments.__version__.startswith('2.3.'):
|
||||
PYGMENT_COLOR = {
|
||||
'black': '#ansiblack',
|
||||
@@ -214,7 +224,7 @@ def set_env_colors(env_colors=None):
|
||||
|
||||
# if there is an issue with the env variable, just set all colors to default and move on
|
||||
if input_error:
|
||||
jc.utils.warning_message('Could not parse JC_COLORS environment variable')
|
||||
jc.utils.warning_message(['Could not parse JC_COLORS environment variable'])
|
||||
color_list = ['default', 'default', 'default', 'default']
|
||||
|
||||
# Try the color set in the JC_COLORS env variable first. If it is set to default, then fall back to default colors
|
||||
@@ -226,9 +236,11 @@ def set_env_colors(env_colors=None):
|
||||
}
|
||||
|
||||
|
||||
def piped_output():
|
||||
"""Return False if stdout is a TTY. True if output is being piped to another program"""
|
||||
return False if sys.stdout.isatty() else True
|
||||
def piped_output(force_color):
|
||||
"""Return False if stdout is a TTY. True if output is being piped to another program
|
||||
and foce_color is True. This allows forcing of ANSI color codes even when using pipes.
|
||||
"""
|
||||
return not sys.stdout.isatty() and not force_color
|
||||
|
||||
|
||||
def ctrlc(signum, frame):
|
||||
@@ -236,9 +248,9 @@ def ctrlc(signum, frame):
|
||||
sys.exit(JC_ERROR_EXIT)
|
||||
|
||||
|
||||
def parser_shortname(parser_argument):
|
||||
def parser_shortname(parser_arg):
|
||||
"""Return short name of the parser with dashes and no -- prefix"""
|
||||
return parser_argument[2:]
|
||||
return parser_arg[2:]
|
||||
|
||||
|
||||
def parser_argument(parser):
|
||||
@@ -325,14 +337,16 @@ def helptext():
|
||||
Parsers:
|
||||
{parsers_string}
|
||||
Options:
|
||||
-a about jc
|
||||
-d debug (-dd for verbose debug)
|
||||
-h help (-h --parser_name for parser documentation)
|
||||
-m monochrome output
|
||||
-p pretty print output
|
||||
-q quiet - suppress parser warnings
|
||||
-r raw JSON output
|
||||
-v version info
|
||||
-a about jc
|
||||
-C force color output even when using pipes (overrides -m)
|
||||
-d debug (-dd for verbose debug)
|
||||
-h help (-h --parser_name for parser documentation)
|
||||
-m monochrome output
|
||||
-p pretty print output
|
||||
-q quiet - suppress parser warnings (-qq to ignore streaming errors)
|
||||
-r raw JSON output
|
||||
-u unbuffer output
|
||||
-v version info
|
||||
|
||||
Examples:
|
||||
Standard Syntax:
|
||||
@@ -359,11 +373,10 @@ def help_doc(options):
|
||||
# load parser module just in time so we don't need to load all modules
|
||||
parser = parser_module(arg)
|
||||
compatible = ', '.join(parser.info.compatible)
|
||||
doc_text = f'''{parser.__doc__}
|
||||
Compatibility: {compatible}
|
||||
|
||||
Version {parser.info.version} by {parser.info.author} ({parser.info.author_email})
|
||||
'''
|
||||
doc_text = \
|
||||
f'{parser.__doc__}\n'\
|
||||
f'Compatibility: {compatible}\n\n'\
|
||||
f'Version {parser.info.version} by {parser.info.author} ({parser.info.author_email})\n'
|
||||
|
||||
return doc_text
|
||||
|
||||
@@ -396,8 +409,7 @@ def json_out(data, pretty=False, env_colors=None, mono=False, piped_out=False):
|
||||
return str(highlight(json.dumps(data, indent=indent, separators=separators, ensure_ascii=False),
|
||||
JsonLexer(), Terminal256Formatter(style=JcStyle))[0:-1])
|
||||
|
||||
else:
|
||||
return json.dumps(data, indent=indent, separators=separators, ensure_ascii=False)
|
||||
return json.dumps(data, indent=indent, separators=separators, ensure_ascii=False)
|
||||
|
||||
|
||||
def magic_parser(args):
|
||||
@@ -414,8 +426,7 @@ def magic_parser(args):
|
||||
if len(args) <= 1 or args[1].startswith('--'):
|
||||
return False, None, None, []
|
||||
|
||||
# correctly parse escape characters and spaces with shlex
|
||||
args_given = ' '.join(map(shlex.quote, args[1:])).split()
|
||||
args_given = args[1:]
|
||||
options = []
|
||||
|
||||
# find the options
|
||||
@@ -425,7 +436,7 @@ def magic_parser(args):
|
||||
return False, None, None, []
|
||||
|
||||
# option found - populate option list
|
||||
elif arg.startswith('-'):
|
||||
if arg.startswith('-'):
|
||||
options.extend(args_given.pop(0)[1:])
|
||||
|
||||
# command found if iterator didn't already stop - stop iterating
|
||||
@@ -456,7 +467,7 @@ def magic_parser(args):
|
||||
found_parser = magic_dict.get(two_word_command, magic_dict.get(one_word_command))
|
||||
|
||||
return (
|
||||
True if found_parser else False, # was a suitable parser found?
|
||||
bool(found_parser), # was a suitable parser found?
|
||||
args_given, # run_command
|
||||
found_parser, # the parser selected
|
||||
options # jc options to preserve
|
||||
@@ -465,7 +476,11 @@ def magic_parser(args):
|
||||
|
||||
def run_user_command(command):
|
||||
"""Use subprocess to run the user's command. Returns the STDOUT, STDERR, and the Exit Code as a tuple."""
|
||||
proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
|
||||
proc = subprocess.Popen(command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
close_fds=False, # Allows inheriting file descriptors. Useful for process substitution
|
||||
universal_newlines=True)
|
||||
stdout, stderr = proc.communicate()
|
||||
|
||||
return (
|
||||
@@ -477,8 +492,7 @@ def run_user_command(command):
|
||||
|
||||
def combined_exit_code(program_exit=0, jc_exit=0):
|
||||
exit_code = program_exit + jc_exit
|
||||
if exit_code > 255:
|
||||
exit_code = 255
|
||||
exit_code = min(exit_code, 255)
|
||||
return exit_code
|
||||
|
||||
|
||||
@@ -515,22 +529,29 @@ def main():
|
||||
|
||||
about = 'a' in options
|
||||
debug = 'd' in options
|
||||
verbose_debug = True if options.count('d') > 1 else False
|
||||
mono = 'm' in options
|
||||
verbose_debug = options.count('d') > 1
|
||||
force_color = 'C' in options
|
||||
mono = ('m' in options or bool(os.getenv('NO_COLOR'))) and not force_color
|
||||
help_me = 'h' in options
|
||||
pretty = 'p' in options
|
||||
quiet = 'q' in options
|
||||
ignore_exceptions = options.count('q') > 1
|
||||
raw = 'r' in options
|
||||
unbuffer = 'u' in options
|
||||
version_info = 'v' in options
|
||||
|
||||
if verbose_debug:
|
||||
jc.tracebackplus.enable(context=11)
|
||||
|
||||
if not pygments_installed:
|
||||
if not PYGMENTS_INSTALLED:
|
||||
mono = True
|
||||
|
||||
if about:
|
||||
print(json_out(about_jc(), pretty=pretty, env_colors=jc_colors, mono=mono, piped_out=piped_output()))
|
||||
print(json_out(about_jc(),
|
||||
pretty=pretty,
|
||||
env_colors=jc_colors,
|
||||
mono=mono,
|
||||
piped_out=piped_output(force_color)))
|
||||
sys.exit(0)
|
||||
|
||||
if help_me:
|
||||
@@ -544,7 +565,10 @@ def main():
|
||||
# if magic syntax used, try to run the command and error if it's not found, etc.
|
||||
magic_stdout, magic_stderr, magic_exit_code = None, None, 0
|
||||
if run_command:
|
||||
run_command_str = ' '.join(run_command)
|
||||
try:
|
||||
run_command_str = shlex.join(run_command) # python 3.8+
|
||||
except AttributeError:
|
||||
run_command_str = ' '.join(run_command) # older python versions
|
||||
|
||||
if valid_command:
|
||||
try:
|
||||
@@ -555,19 +579,26 @@ def main():
|
||||
except FileNotFoundError:
|
||||
if debug:
|
||||
raise
|
||||
else:
|
||||
jc.utils.error_message(f'"{run_command_str}" command could not be found. For details use the -d or -dd option.')
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
jc.utils.error_message([f'"{run_command_str}" command could not be found. For details use the -d or -dd option.'])
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
except OSError:
|
||||
if debug:
|
||||
raise
|
||||
|
||||
jc.utils.error_message([f'"{run_command_str}" command could not be run due to too many open files. For details use the -d or -dd option.'])
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
except Exception:
|
||||
if debug:
|
||||
raise
|
||||
else:
|
||||
jc.utils.error_message(f'"{run_command_str}" command could not be run. For details use the -d or -dd option.')
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
jc.utils.error_message([f'"{run_command_str}" command could not be run. For details use the -d or -dd option.'])
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
elif run_command is not None:
|
||||
jc.utils.error_message(f'"{run_command_str}" cannot be used with Magic syntax. Use "jc -h" for help.')
|
||||
jc.utils.error_message([f'"{run_command_str}" cannot be used with Magic syntax. Use "jc -h" for help.'])
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
# find the correct parser
|
||||
@@ -586,56 +617,79 @@ def main():
|
||||
break
|
||||
|
||||
if not found:
|
||||
jc.utils.error_message('Missing or incorrect arguments. Use "jc -h" for help.')
|
||||
jc.utils.error_message(['Missing or incorrect arguments. Use "jc -h" for help.'])
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
# check for input errors (pipe vs magic)
|
||||
if not sys.stdin.isatty() and magic_stdout:
|
||||
jc.utils.error_message('Piped data and Magic syntax used simultaneously. Use "jc -h" for help.')
|
||||
jc.utils.error_message(['Piped data and Magic syntax used simultaneously. Use "jc -h" for help.'])
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
elif sys.stdin.isatty() and magic_stdout is None:
|
||||
jc.utils.error_message('Missing piped data. Use "jc -h" for help.')
|
||||
jc.utils.error_message(['Missing piped data. Use "jc -h" for help.'])
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
# parse the data
|
||||
data = magic_stdout or sys.stdin.read()
|
||||
|
||||
# parse and print to stdout
|
||||
try:
|
||||
result = parser.parse(data, raw=raw, quiet=quiet)
|
||||
# differentiate between regular and streaming parsers
|
||||
|
||||
# streaming
|
||||
if getattr(parser.info, 'streaming', None):
|
||||
result = parser.parse(sys.stdin, raw=raw, quiet=quiet, ignore_exceptions=ignore_exceptions)
|
||||
for line in result:
|
||||
print(json_out(line,
|
||||
pretty=pretty,
|
||||
env_colors=jc_colors,
|
||||
mono=mono,
|
||||
piped_out=piped_output(force_color)),
|
||||
flush=unbuffer)
|
||||
|
||||
sys.exit(combined_exit_code(magic_exit_code, 0))
|
||||
|
||||
# regular
|
||||
else:
|
||||
data = magic_stdout or sys.stdin.read()
|
||||
result = parser.parse(data, raw=raw, quiet=quiet)
|
||||
print(json_out(result,
|
||||
pretty=pretty,
|
||||
env_colors=jc_colors,
|
||||
mono=mono,
|
||||
piped_out=piped_output(force_color)),
|
||||
flush=unbuffer)
|
||||
|
||||
sys.exit(combined_exit_code(magic_exit_code, 0))
|
||||
|
||||
except (ParseError, LibraryNotInstalled) as e:
|
||||
if debug:
|
||||
raise
|
||||
else:
|
||||
jc.utils.error_message(
|
||||
f'Parser issue with {parser_name}:\n'
|
||||
f' {e}\n'
|
||||
' For details use the -d or -dd option. Use "jc -h" for help.')
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
jc.utils.error_message([f'Parser issue with {parser_name}:',
|
||||
f'{e.__class__.__name__}: {e}',
|
||||
'For details use the -d or -dd option. Use "jc -h" for help.'])
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
except json.JSONDecodeError:
|
||||
if debug:
|
||||
raise
|
||||
|
||||
jc.utils.error_message(['There was an issue generating the JSON output.',
|
||||
'For details use the -d or -dd option.'])
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
except Exception:
|
||||
if debug:
|
||||
raise
|
||||
else:
|
||||
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 or -dd option. Use "jc -h" for help.')
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
# output the json
|
||||
try:
|
||||
print(json_out(result, pretty=pretty, env_colors=jc_colors, mono=mono, piped_out=piped_output()))
|
||||
sys.exit(combined_exit_code(magic_exit_code, 0))
|
||||
streaming_msg = ''
|
||||
if getattr(parser.info, 'streaming', None):
|
||||
streaming_msg = 'Use the -qq option to ignore streaming parser errors.'
|
||||
|
||||
except Exception:
|
||||
if debug:
|
||||
raise
|
||||
else:
|
||||
jc.utils.error_message(
|
||||
'There was an issue generating the JSON output.\n'
|
||||
' For details use the -d or -dd option.')
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
jc.utils.error_message([
|
||||
f'{parser_name} parser could not parse the input data. Did you use the correct parser?',
|
||||
f'{streaming_msg}',
|
||||
'For details use the -d or -dd option. Use "jc -h" for help.'
|
||||
])
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
BIN
jc/man/jc.1.gz
BIN
jc/man/jc.1.gz
Binary file not shown.
@@ -227,7 +227,7 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '1.2'
|
||||
version = '1.3'
|
||||
description = '`acpi` command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
@@ -302,8 +302,8 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible, quiet)
|
||||
jc.utils.input_type_check(data)
|
||||
|
||||
raw_output = []
|
||||
output_line = {}
|
||||
|
||||
@@ -80,7 +80,7 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '1.3'
|
||||
version = '1.4'
|
||||
description = '`airport -I` command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
@@ -130,8 +130,8 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible, quiet)
|
||||
jc.utils.input_type_check(data)
|
||||
|
||||
raw_output = {}
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '1.4'
|
||||
version = '1.5'
|
||||
description = '`airport -s` command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
@@ -166,8 +166,8 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible, quiet)
|
||||
jc.utils.input_type_check(data)
|
||||
|
||||
raw_output = []
|
||||
cleandata = list(filter(None, data.splitlines()))
|
||||
|
||||
@@ -118,7 +118,7 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '1.7'
|
||||
version = '1.8'
|
||||
description = '`arp` command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
@@ -171,8 +171,8 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible, quiet)
|
||||
jc.utils.input_type_check(data)
|
||||
|
||||
raw_output = []
|
||||
cleandata = list(filter(None, data.splitlines()))
|
||||
|
||||
@@ -121,7 +121,7 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '1.4'
|
||||
version = '1.5'
|
||||
description = '`blkid` command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
@@ -176,8 +176,8 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
jc.utils.compatibility(__name__, info.compatible, quiet)
|
||||
jc.utils.input_type_check(data)
|
||||
|
||||
raw_output = []
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user