mirror of
https://github.com/kellyjonbrazil/jc.git
synced 2026-04-03 17:44:07 +02:00
Compare commits
159 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
400f5a44ec | ||
|
|
a2ab5bab91 | ||
|
|
fc8ab27361 | ||
|
|
59f19d33a5 | ||
|
|
dfc9618115 | ||
|
|
8e02e5c75a | ||
|
|
970493ab93 | ||
|
|
64d78956eb | ||
|
|
40c05346f4 | ||
|
|
e9b0bc1409 | ||
|
|
798e6bb7d9 | ||
|
|
12a370deed | ||
|
|
553bfbe1a0 | ||
|
|
52494321fc | ||
|
|
c6c9e06496 | ||
|
|
e3a6c05a58 | ||
|
|
391d06f68d | ||
|
|
99804ea06e | ||
|
|
51935deb2a | ||
|
|
b24d0c3a47 | ||
|
|
762a886d6f | ||
|
|
2c3e9ddfe4 | ||
|
|
c7cd2b63c8 | ||
|
|
f0528ea831 | ||
|
|
5bc5596f60 | ||
|
|
2c27ac46be | ||
|
|
caad840153 | ||
|
|
65bd7e2904 | ||
|
|
c3d7d7db12 | ||
|
|
5605310362 | ||
|
|
17b6efe82e | ||
|
|
a032ae56ae | ||
|
|
eab2f4b056 | ||
|
|
aff86ae6c7 | ||
|
|
7ece9ddc1a | ||
|
|
7cd048e839 | ||
|
|
1e22f610a3 | ||
|
|
5249c972ae | ||
|
|
fd45f856a0 | ||
|
|
c8ab40cd33 | ||
|
|
b2c872925b | ||
|
|
f48e229202 | ||
|
|
799fec92c3 | ||
|
|
87a41c2fca | ||
|
|
7f85de0c46 | ||
|
|
13661b1993 | ||
|
|
51d5c3892d | ||
|
|
e4eab4641a | ||
|
|
9b148e0ba3 | ||
|
|
de28932650 | ||
|
|
5f798d603e | ||
|
|
a0757b2dd3 | ||
|
|
498d51b4e8 | ||
|
|
b06b6bae3f | ||
|
|
b5eaff2137 | ||
|
|
c01bcd3734 | ||
|
|
d75c4068ca | ||
|
|
6aa2d5a3d2 | ||
|
|
065276805f | ||
|
|
a63408c8cf | ||
|
|
69576f6bfa | ||
|
|
19845624e2 | ||
|
|
22ff2964e9 | ||
|
|
d96b3a65a9 | ||
|
|
4989445ef4 | ||
|
|
6770892acd | ||
|
|
d4eba8740f | ||
|
|
9f60760560 | ||
|
|
0a8f8ac934 | ||
|
|
6ae24c8244 | ||
|
|
d3679082a8 | ||
|
|
fb08b42dca | ||
|
|
4aeaa9f42a | ||
|
|
5f5693da04 | ||
|
|
5eb0f61727 | ||
|
|
958e998991 | ||
|
|
b78c1509f6 | ||
|
|
ce184d4d57 | ||
|
|
b4c3714ced | ||
|
|
5b7dfa0438 | ||
|
|
391a388476 | ||
|
|
d9c4e2ed4c | ||
|
|
0c42db38b1 | ||
|
|
2f9be8bf33 | ||
|
|
e8c00155e8 | ||
|
|
cc88fdd9ee | ||
|
|
d9de11ef1d | ||
|
|
0ceda97d09 | ||
|
|
d0dec92ba8 | ||
|
|
d420c008d8 | ||
|
|
f0b32db433 | ||
|
|
bc838eda59 | ||
|
|
afe55b6af0 | ||
|
|
dd3a3ac302 | ||
|
|
f9982a7947 | ||
|
|
07c1be9e9a | ||
|
|
f832b88755 | ||
|
|
0fac757efc | ||
|
|
fc15742065 | ||
|
|
6f2466a131 | ||
|
|
4b90e22f0a | ||
|
|
c493568785 | ||
|
|
1cdf004b77 | ||
|
|
a4ea504261 | ||
|
|
4c2c234c3b | ||
|
|
3d4c0f3e89 | ||
|
|
52fad02903 | ||
|
|
9dcabc057c | ||
|
|
db8c1079dd | ||
|
|
8f954673ab | ||
|
|
79522d1c7d | ||
|
|
a18bf03079 | ||
|
|
c02b6b5d82 | ||
|
|
f99b423284 | ||
|
|
d7d9d45d4f | ||
|
|
90065ec0cd | ||
|
|
51157ebb86 | ||
|
|
96d95c79ca | ||
|
|
e5da34c233 | ||
|
|
f09d657f77 | ||
|
|
0f4b0189f5 | ||
|
|
4666042abb | ||
|
|
027d544c2b | ||
|
|
f1967d0138 | ||
|
|
c1d896027d | ||
|
|
5c2d2a6618 | ||
|
|
997b269b0b | ||
|
|
61257e7525 | ||
|
|
53ee2c3631 | ||
|
|
8bfa0bddec | ||
|
|
ad61e6bc81 | ||
|
|
873b5ba8ac | ||
|
|
6ae50054e2 | ||
|
|
22a35f41bf | ||
|
|
961696c963 | ||
|
|
c7b7f1a5dc | ||
|
|
b5a0d650b1 | ||
|
|
573b279464 | ||
|
|
116e07f161 | ||
|
|
964868c8af | ||
|
|
c8dac32df8 | ||
|
|
72a0016bd8 | ||
|
|
2ad3167434 | ||
|
|
ddabfaa05c | ||
|
|
f857523ca7 | ||
|
|
00d53858e8 | ||
|
|
c008167e66 | ||
|
|
102344a041 | ||
|
|
c865298ef3 | ||
|
|
6ac03faf93 | ||
|
|
49c2701743 | ||
|
|
d1a271b08e | ||
|
|
7388ad19b9 | ||
|
|
2e63cb5fad | ||
|
|
e7f14d02b1 | ||
|
|
873771d05a | ||
|
|
d7de122e36 | ||
|
|
4ef0434f53 | ||
|
|
1aa2c99259 |
31
.github/workflows/pythonapp.yml
vendored
Normal file
31
.github/workflows/pythonapp.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: Test code
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "**/*.py"
|
||||
pull_request:
|
||||
paths:
|
||||
- "**/*.py"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest, windows-latest]
|
||||
python-version: [3.6, 3.7, 3.8]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
- name: Test with unittest
|
||||
run: |
|
||||
python -m unittest discover tests
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,3 +4,4 @@ dist/
|
||||
build/
|
||||
*.egg-info/
|
||||
jc/parsers.old/
|
||||
.github/
|
||||
|
||||
554
README.md
554
README.md
@@ -1,10 +1,9 @@
|
||||
# JC
|
||||
JSON CLI output utility
|
||||
|
||||
`jc` is used to JSONify the output of many standard linux cli tools and file types for easier parsing in scripts. See the **Parsers** section for supported commands.
|
||||
`jc` is used to JSONify the output of many standard linux cli tools and file types for easier parsing in scripts. See the [**Parsers**](#parsers) section for supported commands and file types.
|
||||
|
||||
This allows further command line processing of output with tools like `jq` simply by piping commands:
|
||||
|
||||
```
|
||||
$ ls -l /usr/bin | jc --ls | jq '.[] | select(.size > 50000000)'
|
||||
{
|
||||
@@ -30,10 +29,7 @@ $ jc ls -l /usr/bin | jq '.[] | select(.size > 50000000)'
|
||||
"date": "Aug 14 19:41"
|
||||
}
|
||||
```
|
||||
|
||||
For more information on the motivations for this project, please see my blog post at https://blog.kellybrazil.com/2019/11/26/bringing-the-unix-philosophy-to-the-21st-century/.
|
||||
|
||||
The `jc` parsers can also be used as python modules. In this case the output will be a python dictionary instead of JSON:
|
||||
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:
|
||||
```
|
||||
>>> import jc.parsers.ls
|
||||
>>>
|
||||
@@ -63,7 +59,11 @@ Two representations of the data are possible. The default representation uses a
|
||||
|
||||
To access the raw, pre-processed JSON, use the `-r` cli option or the `raw=True` function parameter in `parse()`.
|
||||
|
||||
Schemas for each parser can be found in the [`docs/parsers`](https://github.com/kellyjonbrazil/jc/tree/dev/docs/parsers) folder.
|
||||
Schemas for each parser can be found in the [`docs/parsers`](https://github.com/kellyjonbrazil/jc/tree/master/docs/parsers) folder.
|
||||
|
||||
Release notes can be found [here](https://blog.kellybrazil.com/category/jc-news/).
|
||||
|
||||
For more information on the motivations for this project, please see my [blog post](https://blog.kellybrazil.com/2019/11/26/bringing-the-unix-philosophy-to-the-21st-century/).
|
||||
|
||||
## Installation
|
||||
```
|
||||
@@ -75,26 +75,29 @@ $ pip3 install --upgrade jc
|
||||
```
|
||||
COMMAND | jc PARSER [OPTIONS]
|
||||
```
|
||||
or
|
||||
```
|
||||
COMMAND | jc [OPTIONS] PARSER
|
||||
```
|
||||
Alternatively, the "magic" syntax can be used by prepending `jc` to the command to be converted. Options can be passed to `jc` immediately before the command is given.
|
||||
Alternatively, the "magic" syntax can be used by prepending `jc` to the command to be converted. Options can be passed to `jc` immediately before the command is given. (Note: command aliases are not supported)
|
||||
```
|
||||
jc [OPTIONS] COMMAND
|
||||
```
|
||||
The JSON output can be compact (default) or pretty formatted with the `-p` option.
|
||||
|
||||
### Parsers
|
||||
- `--airport` enables the `airport -I` command parser (OSX)
|
||||
- `--airport-s` enables the `airport -s` command parser (OSX)
|
||||
- `--arp` enables the `arp` command parser
|
||||
- `--blkid` enables the `blkid` command parser
|
||||
- `--crontab` enables the `crontab` command and file parser
|
||||
- `--crontab-u` enables the `crontab` file parser with user support
|
||||
- `--csv` enables the `CSV` file parser
|
||||
- `--df` enables the `df` command parser
|
||||
- `--dig` enables the `dig` command parser
|
||||
- `--du` enables the `du` command parser
|
||||
- `--env` enables the `env` command parser
|
||||
- `--file` enables the `file` command parser
|
||||
- `--free` enables the `free` command parser
|
||||
- `--fstab` enables the `/etc/fstab` file parser
|
||||
- `--group` enables the `/etc/group` file parser
|
||||
- `--gshadow` enables the `/etc/gshadow` file parser
|
||||
- `--history` enables the `history` command parser
|
||||
- `--hosts` enables the `/etc/hosts` file parser
|
||||
- `--id` enables the `id` command parser
|
||||
@@ -102,25 +105,31 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio
|
||||
- `--ini` enables the `INI` file parser
|
||||
- `--iptables` enables the `iptables` command parser
|
||||
- `--jobs` enables the `jobs` command parser
|
||||
- `--last` enables the `last` and `lastb` command parser
|
||||
- `--ls` enables the `ls` command parser
|
||||
- `--lsblk` enables the `lsblk` command parser
|
||||
- `--lsmod` enables the `lsmod` command parser
|
||||
- `--lsof` enables the `lsof` command parser
|
||||
- `--mount` enables the `mount` command parser
|
||||
- `--netstat` enables the `netstat` command parser
|
||||
- `--ntpq` enables the `ntpq -p` command parser
|
||||
- `--passwd` enables the `/etc/passwd` file parser
|
||||
- `--pip-list` enables the `pip list` command parser
|
||||
- `--pip-show` enables the `pip show` command parser
|
||||
- `--ps` enables the `ps` command parser
|
||||
- `--route` enables the `route` command parser
|
||||
- `--shadow` enables the `/etc/shadow` file parser
|
||||
- `--ss` enables the `ss` command parser
|
||||
- `--stat` enables the `stat` command parser
|
||||
- `--systemctl` enables the `systemctl` command parser
|
||||
- `--systemctl-lj` enables the `systemctl list-jobs` command parser
|
||||
- `--systemctl-ls` enables the `systemctl list-sockets` command parser
|
||||
- `--systemctl-luf` enables the `systemctl list-unit-files` command parser
|
||||
- `--timedatectl` enables the `timedatectl status` command parser
|
||||
- `--uname` enables the `uname -a` command parser
|
||||
- `--uptime` enables the `uptime` command parser
|
||||
- `--w` enables the `w` command parser
|
||||
- `--who` enables the `who` command parser
|
||||
- `--xml` enables the `XML` file parser
|
||||
- `--yaml` enables the `YAML` file parser
|
||||
|
||||
@@ -131,7 +140,95 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio
|
||||
- `-q` quiet mode. Suppresses warning messages
|
||||
- `-r` raw output. Provides a more literal JSON output with all values as text and no additional sematic processing
|
||||
|
||||
## 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.
|
||||
|
||||
## Compatibility
|
||||
Some parsers like `ls`, `ps`, `dig`, etc. will work on any platform. Other parsers that are platform-specific will generate a warning message if they are used on an unsupported platform. To see all parser information, including compatibility, run `jc -ap`.
|
||||
|
||||
|
||||
You may still use a parser on an unsupported platform - for example, you may want to parse a file with linux `lsof` output on an OSX laptop. In that case you can suppress the warning message with the `-q` cli option or the `quiet=True` function parameter in `parse()`:
|
||||
|
||||
```
|
||||
$ cat lsof.out | jc --lsof -q
|
||||
```
|
||||
|
||||
Tested on:
|
||||
- Centos 7.7
|
||||
- Ubuntu 18.4
|
||||
- OSX 10.11.6
|
||||
- OSX 10.14.6
|
||||
|
||||
## Acknowledgments
|
||||
- CI automation and code optimizations from https://github.com/philippeitis
|
||||
- `ifconfig-parser` module from https://github.com/KnightWhoSayNi/ifconfig-parser
|
||||
- `xmltodict` module from https://github.com/martinblech/xmltodict by Martín Blech
|
||||
- `ruamel.yaml` library from https://pypi.org/project/ruamel.yaml by Anthon van der Neut
|
||||
- Parsing code from Conor Heine at https://gist.github.com/cahna/43a1a3ff4d075bcd71f9d7120037a501 adapted for some parsers
|
||||
- Excellent constructive feedback from Ilya Sher (https://github.com/ilyash-b)
|
||||
|
||||
## Examples
|
||||
### airport -I
|
||||
```
|
||||
$ airport -I | jc --airport -p
|
||||
{
|
||||
"agrctlrssi": -66,
|
||||
"agrextrssi": 0,
|
||||
"agrctlnoise": -90,
|
||||
"agrextnoise": 0,
|
||||
"state": "running",
|
||||
"op_mode": "station",
|
||||
"lasttxrate": 195,
|
||||
"maxrate": 867,
|
||||
"lastassocstatus": 0,
|
||||
"802_11_auth": "open",
|
||||
"link_auth": "wpa2-psk",
|
||||
"bssid": "3c:37:86:15:ad:f9",
|
||||
"ssid": "SnazzleDazzle",
|
||||
"mcs": 0,
|
||||
"channel": "48,80"
|
||||
}
|
||||
```
|
||||
### airport -s
|
||||
```
|
||||
$ airport -s | jc --airport-s -p
|
||||
[
|
||||
{
|
||||
"ssid": "DIRECT-4A-HP OfficeJet 3830",
|
||||
"bssid": "00:67:eb:2a:a7:3b",
|
||||
"rssi": -90,
|
||||
"channel": "6",
|
||||
"ht": true,
|
||||
"cc": "--",
|
||||
"security": [
|
||||
"WPA2(PSK/AES/AES)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ssid": "Latitude38",
|
||||
"bssid": "c0:ff:d5:d2:7a:f3",
|
||||
"rssi": -85,
|
||||
"channel": "11",
|
||||
"ht": true,
|
||||
"cc": "US",
|
||||
"security": [
|
||||
"WPA2(PSK/AES/AES)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ssid": "xfinitywifi",
|
||||
"bssid": "6e:e3:0e:b8:45:99",
|
||||
"rssi": -83,
|
||||
"channel": "11",
|
||||
"ht": true,
|
||||
"cc": "US",
|
||||
"security": [
|
||||
"NONE"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### arp
|
||||
```
|
||||
$ arp | jc --arp -p # or: jc -p arp
|
||||
@@ -185,6 +282,53 @@ $ arp -a | jc --arp -p # or: jc -p arp -a
|
||||
}
|
||||
]
|
||||
```
|
||||
### blkid
|
||||
```
|
||||
$ blkid | jc --blkid -p # or: jc -p blkid
|
||||
[
|
||||
{
|
||||
"device": "/dev/sda1",
|
||||
"uuid": "05d927ab-5875-49e4-ada1-7f46cb32c932",
|
||||
"type": "xfs"
|
||||
},
|
||||
{
|
||||
"device": "/dev/sda2",
|
||||
"uuid": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"type": "LVM2_member"
|
||||
},
|
||||
{
|
||||
"device": "/dev/mapper/centos-root",
|
||||
"uuid": "07d718ff-950c-4e5b-98f0-42a1147c77d9",
|
||||
"type": "xfs"
|
||||
},
|
||||
{
|
||||
"device": "/dev/mapper/centos-swap",
|
||||
"uuid": "615eb89a-bcbf-46fd-80e3-c483ff5c931f",
|
||||
"type": "swap"
|
||||
}
|
||||
]
|
||||
```
|
||||
```
|
||||
$ sudo blkid -o udev -ip /dev/sda2 | jc --blkid -p # or: sudo jc -p blkid -o udev -ip /dev/sda2
|
||||
[
|
||||
{
|
||||
"id_fs_uuid": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"id_fs_uuid_enc": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"id_fs_version": "LVM2\x20001",
|
||||
"id_fs_type": "LVM2_member",
|
||||
"id_fs_usage": "raid",
|
||||
"id_iolimit_minimum_io_size": 512,
|
||||
"id_iolimit_physical_sector_size": 512,
|
||||
"id_iolimit_logical_sector_size": 512,
|
||||
"id_part_entry_scheme": "dos",
|
||||
"id_part_entry_type": "0x8e",
|
||||
"id_part_entry_number": 2,
|
||||
"id_part_entry_offset": 2099200,
|
||||
"id_part_entry_size": 39843840,
|
||||
"id_part_entry_disk": "8:0"
|
||||
}
|
||||
]
|
||||
```
|
||||
### crontab
|
||||
```
|
||||
$ cat /etc/crontab | jc --crontab -p # or: jc -p crontab -l
|
||||
@@ -332,6 +476,53 @@ $ cat /etc/crontab | jc --crontab-u -p
|
||||
]
|
||||
}
|
||||
```
|
||||
### CSV files
|
||||
```
|
||||
$ 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 -p
|
||||
[
|
||||
{
|
||||
"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"
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### df
|
||||
```
|
||||
$ df | jc --df -p # or: jc -p df
|
||||
@@ -571,6 +762,41 @@ $ env | jc --env -p # or: jc -p env
|
||||
...
|
||||
]
|
||||
```
|
||||
### file
|
||||
```
|
||||
$ file * | jc --file -p
|
||||
[
|
||||
{
|
||||
"filename": "Applications",
|
||||
"type": "directory"
|
||||
},
|
||||
{
|
||||
"filename": "another file with spaces",
|
||||
"type": "empty"
|
||||
},
|
||||
{
|
||||
"filename": "argstest.py",
|
||||
"type": "Python script text executable, ASCII text"
|
||||
},
|
||||
{
|
||||
"filename": "blkid-p.out",
|
||||
"type": "ASCII text"
|
||||
},
|
||||
{
|
||||
"filename": "blkid-pi.out",
|
||||
"type": "ASCII text, with very long lines"
|
||||
},
|
||||
{
|
||||
"filename": "cd_catalog.xml",
|
||||
"type": "XML 1.0 document text, ASCII text, with CRLF line terminators"
|
||||
},
|
||||
{
|
||||
"filename": "centosserial.sh",
|
||||
"type": "Bourne-Again shell script text executable, UTF-8 Unicode text"
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### free
|
||||
```
|
||||
$ free | jc --free -p # or: jc -p free
|
||||
@@ -622,9 +848,71 @@ $ cat /etc/fstab | jc --fstab -p
|
||||
}
|
||||
]
|
||||
```
|
||||
### /etc/group file
|
||||
```
|
||||
$ cat /etc/group | jc --group -p
|
||||
[
|
||||
{
|
||||
"group_name": "nobody",
|
||||
"password": "*",
|
||||
"gid": -2,
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "nogroup",
|
||||
"password": "*",
|
||||
"gid": -1,
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "wheel",
|
||||
"password": "*",
|
||||
"gid": 0,
|
||||
"members": [
|
||||
"root"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "certusers",
|
||||
"password": "*",
|
||||
"gid": 29,
|
||||
"members": [
|
||||
"root",
|
||||
"_jabber",
|
||||
"_postfix",
|
||||
"_cyrus",
|
||||
"_calendar",
|
||||
"_dovecot"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### /etc/gshadow file
|
||||
```
|
||||
$ cat /etc/gshadow | jc --gshadow -p
|
||||
[
|
||||
{
|
||||
"group_name": "root",
|
||||
"password": "*",
|
||||
"administrators": [],
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "adm",
|
||||
"password": "*",
|
||||
"administrators": [],
|
||||
"members": [
|
||||
"syslog",
|
||||
"joeuser"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### history
|
||||
```
|
||||
$ history | jc --history -p # or: jc -p history
|
||||
$ history | jc --history -p
|
||||
[
|
||||
{
|
||||
"line": 118,
|
||||
@@ -922,6 +1210,36 @@ $ jobs -l | jc --jobs -p # or: jc -p jobs
|
||||
}
|
||||
]
|
||||
```
|
||||
### last and lastb
|
||||
```
|
||||
$ last | jc --last -p # or: jc -p last
|
||||
[
|
||||
{
|
||||
"user": "joeuser",
|
||||
"tty": "ttys002",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 14:31",
|
||||
"logout": "still logged in"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"tty": "ttys003",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 10:38",
|
||||
"logout": "10:38",
|
||||
"duration": "00:00"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"tty": "ttys003",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 10:18",
|
||||
"logout": "10:18",
|
||||
"duration": "00:00"
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### ls
|
||||
```
|
||||
$ ls -l /usr/bin | jc --ls -p # or: jc -p ls -l /usr/bin
|
||||
@@ -1268,6 +1586,72 @@ $ sudo netstat -apee | jc --netstat -p # or: sudo jc -p netstat -apee
|
||||
...
|
||||
]
|
||||
```
|
||||
### ntpq
|
||||
```
|
||||
$ ntpq -p | jc --ntpq -p # or: jc -p ntpq -p
|
||||
[
|
||||
{
|
||||
"remote": "44.190.6.254",
|
||||
"refid": "127.67.113.92",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": 1,
|
||||
"poll": 64,
|
||||
"reach": 1,
|
||||
"delay": 23.399,
|
||||
"offset": -2.805,
|
||||
"jitter": 2.131,
|
||||
"state": null
|
||||
},
|
||||
{
|
||||
"remote": "mirror1.sjc02.s",
|
||||
"refid": "216.218.254.202",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": 2,
|
||||
"poll": 64,
|
||||
"reach": 1,
|
||||
"delay": 29.325,
|
||||
"offset": 1.044,
|
||||
"jitter": 4.069,
|
||||
"state": null
|
||||
}
|
||||
]
|
||||
```
|
||||
### /etc/passwd file
|
||||
```
|
||||
$ cat /etc/passwd | jc --passwd -p
|
||||
[
|
||||
{
|
||||
"username": "nobody",
|
||||
"password": "*",
|
||||
"uid": -2,
|
||||
"gid": -2,
|
||||
"comment": "Unprivileged User",
|
||||
"home": "/var/empty",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"comment": "System Administrator",
|
||||
"home": "/var/root",
|
||||
"shell": "/bin/sh"
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"uid": 1,
|
||||
"gid": 1,
|
||||
"comment": "System Services",
|
||||
"home": "/var/root",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### pip list
|
||||
```
|
||||
$ pip list | jc --pip-list -p # or: jc -p pip list # or: jc -p pip3 list
|
||||
@@ -1445,6 +1829,43 @@ $ route -ee | jc --route -p # or: jc -p route -ee
|
||||
}
|
||||
]
|
||||
```
|
||||
### /etc/shadow file
|
||||
```
|
||||
$ sudo cat /etc/shadow | jc --shadow -p
|
||||
[
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
{
|
||||
"username": "bin",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### ss
|
||||
```
|
||||
$ sudo ss -a | jc --ss -p # or: sudo jc -p ss -a
|
||||
@@ -1704,6 +2125,20 @@ $ systemctl list-unit-files | jc --systemctl-luf -p # or: jc -p system
|
||||
...
|
||||
]
|
||||
```
|
||||
### timedatectl status
|
||||
```
|
||||
$ timedatectl | jc --timedatectl -p
|
||||
{
|
||||
"local_time": "Tue 2020-03-10 17:53:21 PDT",
|
||||
"universal_time": "Wed 2020-03-11 00:53:21 UTC",
|
||||
"rtc_time": "Wed 2020-03-11 00:53:21",
|
||||
"time_zone": "America/Los_Angeles (PDT, -0700)",
|
||||
"ntp_enabled": true,
|
||||
"ntp_synchronized": true,
|
||||
"rtc_in_local_tz": false,
|
||||
"dst_active": true
|
||||
}
|
||||
```
|
||||
### uname -a
|
||||
```
|
||||
$ uname -a | jc --uname -p # or: jc -p uname -a
|
||||
@@ -1766,6 +2201,67 @@ $ w | jc --w -p # or: jc -p w
|
||||
}
|
||||
]
|
||||
```
|
||||
### who
|
||||
```
|
||||
$ who | jc --who -p # or: jc -p who
|
||||
[
|
||||
{
|
||||
"user": "joeuser",
|
||||
"tty": "ttyS0",
|
||||
"time": "2020-03-02 02:52"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"tty": "pts/0",
|
||||
"time": "2020-03-02 05:15",
|
||||
"from": "192.168.71.1"
|
||||
}
|
||||
]
|
||||
```
|
||||
```
|
||||
$ who -a | jc --who -p # or: jc -p who -a
|
||||
[
|
||||
{
|
||||
"event": "reboot",
|
||||
"time": "Feb 7 23:31",
|
||||
"pid": 1
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "-",
|
||||
"tty": "console",
|
||||
"time": "Feb 7 23:32",
|
||||
"idle": "old",
|
||||
"pid": 105
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys000",
|
||||
"time": "Feb 13 16:44",
|
||||
"idle": ".",
|
||||
"pid": 51217,
|
||||
"comment": "term=0 exit=0"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "?",
|
||||
"tty": "ttys003",
|
||||
"time": "Feb 28 08:59",
|
||||
"idle": "01:36",
|
||||
"pid": 41402
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys004",
|
||||
"time": "Mar 1 16:35",
|
||||
"idle": ".",
|
||||
"pid": 15679,
|
||||
"from": "192.168.1.5"
|
||||
}
|
||||
]
|
||||
```
|
||||
### XML files
|
||||
```
|
||||
$ cat cd_catalog.xml
|
||||
@@ -1869,34 +2365,4 @@ $ cat istio.yaml | jc --yaml -p
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
## TODO
|
||||
Future parsers:
|
||||
- /proc files
|
||||
- /sys files
|
||||
|
||||
## Contributions
|
||||
Feel free to add/improve code or parsers! You can use the `jc/parsers/foo.py` parser as a template and submit your parser with a pull request.
|
||||
|
||||
## Compatibility
|
||||
Some parsers like `ls`, `ps`, `dig`, etc. will work on any platform. Other parsers that are platform-specific will generate a warning message if they are used on an unsupported platform. To see all parser information, including compatibility, run `jc -a -p`.
|
||||
|
||||
|
||||
You may still use a parser on an unsupported platform - for example, you may want to parse a file with linux `lsof` output on an OSX laptop. In that case you can suppress the warning message with the `-q` cli option or the `quiet=True` function parameter in `parse()`:
|
||||
|
||||
```
|
||||
$ cat lsof.out | jc --lsof -q
|
||||
```
|
||||
|
||||
Tested on:
|
||||
- Centos 7.7
|
||||
- Ubuntu 18.4
|
||||
- OSX 10.11.6
|
||||
- OSX 10.14.6
|
||||
|
||||
## Acknowledgments
|
||||
- `ifconfig-parser` module from https://github.com/KnightWhoSayNi/ifconfig-parser
|
||||
- `xmltodict` module from https://github.com/martinblech/xmltodict by Martín Blech
|
||||
- `ruamel.yaml` library from https://pypi.org/project/ruamel.yaml by Anthon van der Neut
|
||||
- Parsing code from Conor Heine at https://gist.github.com/cahna/43a1a3ff4d075bcd71f9d7120037a501 adapted for some parsers
|
||||
- Excellent constructive feedback from Ilya Sher (https://github.com/ilyash-b)
|
||||
```
|
||||
@@ -1,5 +1,35 @@
|
||||
jc changelog
|
||||
|
||||
20200311 v1.9.0
|
||||
- Added ntpq command parser
|
||||
- Added timedatectl status command parser
|
||||
- Added airport -I and airport -s command parser
|
||||
- Added file command parser
|
||||
- Optimized history command parser by https://github.com/philippeitis
|
||||
- Magic syntax fix for certain edge cases
|
||||
|
||||
20200308 v1.8.1
|
||||
- CLI optimizations by https://github.com/philippeitis
|
||||
- Refactored magic syntax function and added tests (https://github.com/philippeitis)
|
||||
- Github actions for CI testing on multiple platforms by https://github.com/philippeitis
|
||||
- Updated ls parser to fix parsing error in OSX with -lR when there are empty folders
|
||||
|
||||
20200303 v1.8.0
|
||||
- Added blkid command parser
|
||||
- Added last and lastb command parser
|
||||
- Added who command parser
|
||||
- Added CSV file parser
|
||||
- Added /etc/passwd file parser
|
||||
- Added /etc/shadow file parser
|
||||
- Added /etc/group file parser
|
||||
- Added /etc/gshadow file parser
|
||||
|
||||
20200227 v1.7.5
|
||||
- Updated ls parser to support filenames with newline characters
|
||||
|
||||
20200219 v1.7.4
|
||||
- Updated ls parser to support multiple directories, globbing, and -R (recursive)
|
||||
|
||||
20200211 v1.7.3
|
||||
- Add alternative 'magic' syntax: e.g. `jc ls -al`
|
||||
- Options can now be condensed (e.g. -prq is equivalant to -p -r -q)
|
||||
|
||||
13
docgen.sh
13
docgen.sh
@@ -4,15 +4,22 @@
|
||||
cd jc
|
||||
pydocmd simple jc+ > ../docs/readme.md
|
||||
pydocmd simple utils+ > ../docs/utils.md
|
||||
pydocmd simple jc.parsers.airport+ > ../docs/parsers/airport.md
|
||||
pydocmd simple jc.parsers.airport_s+ > ../docs/parsers/airport_s.md
|
||||
pydocmd simple jc.parsers.arp+ > ../docs/parsers/arp.md
|
||||
pydocmd simple jc.parsers.blkid+ > ../docs/parsers/blkid.md
|
||||
pydocmd simple jc.parsers.crontab+ > ../docs/parsers/crontab.md
|
||||
pydocmd simple jc.parsers.crontab_u+ > ../docs/parsers/crontab_u.md
|
||||
pydocmd simple jc.parsers.csv+ > ../docs/parsers/csv.md
|
||||
pydocmd simple jc.parsers.df+ > ../docs/parsers/df.md
|
||||
pydocmd simple jc.parsers.dig+ > ../docs/parsers/dig.md
|
||||
pydocmd simple jc.parsers.du+ > ../docs/parsers/du.md
|
||||
pydocmd simple jc.parsers.env+ > ../docs/parsers/env.md
|
||||
pydocmd simple jc.parsers.file+ > ../docs/parsers/file.md
|
||||
pydocmd simple jc.parsers.free+ > ../docs/parsers/free.md
|
||||
pydocmd simple jc.parsers.fstab+ > ../docs/parsers/fstab.md
|
||||
pydocmd simple jc.parsers.group+ > ../docs/parsers/group.md
|
||||
pydocmd simple jc.parsers.gshadow+ > ../docs/parsers/gshadow.md
|
||||
pydocmd simple jc.parsers.history+ > ../docs/parsers/history.md
|
||||
pydocmd simple jc.parsers.hosts+ > ../docs/parsers/hosts.md
|
||||
pydocmd simple jc.parsers.id+ > ../docs/parsers/id.md
|
||||
@@ -20,24 +27,30 @@ pydocmd simple jc.parsers.ifconfig+ > ../docs/parsers/ifconfig.md
|
||||
pydocmd simple jc.parsers.ini+ > ../docs/parsers/ini.md
|
||||
pydocmd simple jc.parsers.iptables+ > ../docs/parsers/iptables.md
|
||||
pydocmd simple jc.parsers.jobs+ > ../docs/parsers/jobs.md
|
||||
pydocmd simple jc.parsers.last+ > ../docs/parsers/last.md
|
||||
pydocmd simple jc.parsers.ls+ > ../docs/parsers/ls.md
|
||||
pydocmd simple jc.parsers.lsblk+ > ../docs/parsers/lsblk.md
|
||||
pydocmd simple jc.parsers.lsmod+ > ../docs/parsers/lsmod.md
|
||||
pydocmd simple jc.parsers.lsof+ > ../docs/parsers/lsof.md
|
||||
pydocmd simple jc.parsers.mount+ > ../docs/parsers/mount.md
|
||||
pydocmd simple jc.parsers.netstat+ > ../docs/parsers/netstat.md
|
||||
pydocmd simple jc.parsers.ntpq+ > ../docs/parsers/ntpq.md
|
||||
pydocmd simple jc.parsers.passwd+ > ../docs/parsers/passwd.md
|
||||
pydocmd simple jc.parsers.pip_list+ > ../docs/parsers/pip_list.md
|
||||
pydocmd simple jc.parsers.pip_show+ > ../docs/parsers/pip_show.md
|
||||
pydocmd simple jc.parsers.ps+ > ../docs/parsers/ps.md
|
||||
pydocmd simple jc.parsers.route+ > ../docs/parsers/route.md
|
||||
pydocmd simple jc.parsers.shadow+ > ../docs/parsers/shadow.md
|
||||
pydocmd simple jc.parsers.ss+ > ../docs/parsers/ss.md
|
||||
pydocmd simple jc.parsers.stat+ > ../docs/parsers/stat.md
|
||||
pydocmd simple jc.parsers.systemctl+ > ../docs/parsers/systemctl.md
|
||||
pydocmd simple jc.parsers.systemctl_lj+ > ../docs/parsers/systemctl_lj.md
|
||||
pydocmd simple jc.parsers.systemctl_ls+ > ../docs/parsers/systemctl_ls.md
|
||||
pydocmd simple jc.parsers.systemctl_luf+ > ../docs/parsers/systemctl_luf.md
|
||||
pydocmd simple jc.parsers.timedatectl+ > ../docs/parsers/timedatectl.md
|
||||
pydocmd simple jc.parsers.uname+ > ../docs/parsers/uname.md
|
||||
pydocmd simple jc.parsers.uptime+ > ../docs/parsers/uptime.md
|
||||
pydocmd simple jc.parsers.w+ > ../docs/parsers/w.md
|
||||
pydocmd simple jc.parsers.who+ > ../docs/parsers/who.md
|
||||
pydocmd simple jc.parsers.xml+ > ../docs/parsers/xml.md
|
||||
pydocmd simple jc.parsers.yaml+ > ../docs/parsers/yaml.md
|
||||
|
||||
109
docs/parsers/airport.md
Normal file
109
docs/parsers/airport.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# jc.parsers.airport
|
||||
jc - JSON CLI output utility airport -I Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --airport as the first argument if the piped input is coming from airport -I (OSX)
|
||||
|
||||
This program can be found at:
|
||||
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport
|
||||
|
||||
Compatibility:
|
||||
|
||||
'darwin'
|
||||
|
||||
Examples:
|
||||
|
||||
$ airport -I | jc --airport -p
|
||||
{
|
||||
"agrctlrssi": -66,
|
||||
"agrextrssi": 0,
|
||||
"agrctlnoise": -90,
|
||||
"agrextnoise": 0,
|
||||
"state": "running",
|
||||
"op_mode": "station",
|
||||
"lasttxrate": 195,
|
||||
"maxrate": 867,
|
||||
"lastassocstatus": 0,
|
||||
"802_11_auth": "open",
|
||||
"link_auth": "wpa2-psk",
|
||||
"bssid": "3c:37:86:15:ad:f9",
|
||||
"ssid": "SnazzleDazzle",
|
||||
"mcs": 0,
|
||||
"channel": "48,80"
|
||||
}
|
||||
|
||||
$ airport -I | jc --airport -p -r
|
||||
{
|
||||
"agrctlrssi": "-66",
|
||||
"agrextrssi": "0",
|
||||
"agrctlnoise": "-90",
|
||||
"agrextnoise": "0",
|
||||
"state": "running",
|
||||
"op_mode": "station",
|
||||
"lasttxrate": "195",
|
||||
"maxrate": "867",
|
||||
"lastassocstatus": "0",
|
||||
"802_11_auth": "open",
|
||||
"link_auth": "wpa2-psk",
|
||||
"bssid": "3c:37:86:15:ad:f9",
|
||||
"ssid": "SnazzleDazzle",
|
||||
"mcs": "0",
|
||||
"channel": "48,80"
|
||||
}
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Structured data with the following schema:
|
||||
|
||||
{
|
||||
"agrctlrssi": integer,
|
||||
"agrextrssi": integer,
|
||||
"agrctlnoise": integer,
|
||||
"agrextnoise": integer,
|
||||
"state": string,
|
||||
"op_mode": string,
|
||||
"lasttxrate": integer,
|
||||
"maxrate": integer,
|
||||
"lastassocstatus": integer,
|
||||
"802_11_auth": string,
|
||||
"link_auth": string,
|
||||
"bssid": string,
|
||||
"ssid": string,
|
||||
"mcs": integer,
|
||||
"channel": string
|
||||
}
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
136
docs/parsers/airport_s.md
Normal file
136
docs/parsers/airport_s.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# jc.parsers.airport_s
|
||||
jc - JSON CLI output utility airport -s Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --airport as the first argument if the piped input is coming from airport -s (OSX)
|
||||
|
||||
This program can be found at:
|
||||
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport
|
||||
|
||||
Compatibility:
|
||||
|
||||
'darwin'
|
||||
|
||||
Examples:
|
||||
|
||||
$ airport -s | jc --airport-s -p
|
||||
[
|
||||
{
|
||||
"ssid": "DIRECT-4A-HP OfficeJet 3830",
|
||||
"bssid": "00:67:eb:2a:a7:3b",
|
||||
"rssi": -90,
|
||||
"channel": "6",
|
||||
"ht": true,
|
||||
"cc": "--",
|
||||
"security": [
|
||||
"WPA2(PSK/AES/AES)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ssid": "Latitude38",
|
||||
"bssid": "c0:ff:d5:d2:7a:f3",
|
||||
"rssi": -85,
|
||||
"channel": "11",
|
||||
"ht": true,
|
||||
"cc": "US",
|
||||
"security": [
|
||||
"WPA2(PSK/AES/AES)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ssid": "xfinitywifi",
|
||||
"bssid": "6e:e3:0e:b8:45:99",
|
||||
"rssi": -83,
|
||||
"channel": "11",
|
||||
"ht": true,
|
||||
"cc": "US",
|
||||
"security": [
|
||||
"NONE"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ airport -s | jc --airport -p -r
|
||||
[
|
||||
{
|
||||
"ssid": "DIRECT-F3-HP ENVY 5660 series",
|
||||
"bssid": "b0:5a:da:6f:0a:d4",
|
||||
"rssi": "-93",
|
||||
"channel": "1",
|
||||
"ht": "Y",
|
||||
"cc": "--",
|
||||
"security": "WPA2(PSK/AES/AES)"
|
||||
},
|
||||
{
|
||||
"ssid": "YouAreInfected-5",
|
||||
"bssid": "5c:e3:0e:c2:85:da",
|
||||
"rssi": "-85",
|
||||
"channel": "36",
|
||||
"ht": "Y",
|
||||
"cc": "US",
|
||||
"security": "WPA(PSK/AES,TKIP/TKIP) WPA2(PSK/AES,TKIP/TKIP)"
|
||||
},
|
||||
{
|
||||
"ssid": "YuanFamily",
|
||||
"bssid": "5c:e3:0e:b8:5f:9a",
|
||||
"rssi": "-84",
|
||||
"channel": "11",
|
||||
"ht": "Y",
|
||||
"cc": "US",
|
||||
"security": "WPA(PSK/AES,TKIP/TKIP) WPA2(PSK/AES,TKIP/TKIP)"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
[
|
||||
{
|
||||
"ssid": string,
|
||||
"bssid": string,
|
||||
"rssi": integer,
|
||||
"channel": string,
|
||||
"ht": boolean,
|
||||
"cc": string,
|
||||
"security": [
|
||||
string,
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
148
docs/parsers/blkid.md
Normal file
148
docs/parsers/blkid.md
Normal file
@@ -0,0 +1,148 @@
|
||||
# jc.parsers.blkid
|
||||
jc - JSON CLI output utility blkid Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --blkid as the first argument if the piped input is coming from blkid
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ blkid | jc --blkid -p
|
||||
[
|
||||
{
|
||||
"device": "/dev/sda1",
|
||||
"uuid": "05d927ab-5875-49e4-ada1-7f46cb32c932",
|
||||
"type": "xfs"
|
||||
},
|
||||
{
|
||||
"device": "/dev/sda2",
|
||||
"uuid": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"type": "LVM2_member"
|
||||
},
|
||||
{
|
||||
"device": "/dev/mapper/centos-root",
|
||||
"uuid": "07d718ff-950c-4e5b-98f0-42a1147c77d9",
|
||||
"type": "xfs"
|
||||
},
|
||||
{
|
||||
"device": "/dev/mapper/centos-swap",
|
||||
"uuid": "615eb89a-bcbf-46fd-80e3-c483ff5c931f",
|
||||
"type": "swap"
|
||||
}
|
||||
]
|
||||
|
||||
$ sudo blkid -o udev -ip /dev/sda2 | jc --blkid -p
|
||||
[
|
||||
{
|
||||
"id_fs_uuid": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"id_fs_uuid_enc": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"id_fs_version": "LVM2\x20001",
|
||||
"id_fs_type": "LVM2_member",
|
||||
"id_fs_usage": "raid",
|
||||
"id_iolimit_minimum_io_size": 512,
|
||||
"id_iolimit_physical_sector_size": 512,
|
||||
"id_iolimit_logical_sector_size": 512,
|
||||
"id_part_entry_scheme": "dos",
|
||||
"id_part_entry_type": "0x8e",
|
||||
"id_part_entry_number": 2,
|
||||
"id_part_entry_offset": 2099200,
|
||||
"id_part_entry_size": 39843840,
|
||||
"id_part_entry_disk": "8:0"
|
||||
}
|
||||
]
|
||||
|
||||
$ sudo blkid -ip /dev/sda1 | jc --blkid -p -r
|
||||
[
|
||||
{
|
||||
"devname": "/dev/sda1",
|
||||
"uuid": "05d927bb-5875-49e3-ada1-7f46cb31c932",
|
||||
"type": "xfs",
|
||||
"usage": "filesystem",
|
||||
"minimum_io_size": "512",
|
||||
"physical_sector_size": "512",
|
||||
"logical_sector_size": "512",
|
||||
"part_entry_scheme": "dos",
|
||||
"part_entry_type": "0x83",
|
||||
"part_entry_flags": "0x80",
|
||||
"part_entry_number": "1",
|
||||
"part_entry_offset": "2048",
|
||||
"part_entry_size": "2097152",
|
||||
"part_entry_disk": "8:0"
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"device": string,
|
||||
"uuid": string,
|
||||
"type": string,
|
||||
"usage": string,
|
||||
"part_entry_scheme": string,
|
||||
"part_entry_type": string,
|
||||
"part_entry_flags": string,
|
||||
"part_entry_number": integer,
|
||||
"part_entry_offset": integer,
|
||||
"part_entry_size": integer,
|
||||
"part_entry_disk": string,
|
||||
"id_fs_uuid": string,
|
||||
"id_fs_uuid_enc": string,
|
||||
"id_fs_version": string,
|
||||
"id_fs_type": string,
|
||||
"id_fs_usage": string,
|
||||
"id_part_entry_scheme": string,
|
||||
"id_part_entry_type": string,
|
||||
"id_part_entry_flags": string,
|
||||
"id_part_entry_number": integer,
|
||||
"id_part_entry_offset": integer,
|
||||
"id_part_entry_size": integer,
|
||||
"id_iolimit_minimum_io_size": integer,
|
||||
"id_iolimit_physical_sector_size": integer,
|
||||
"id_iolimit_logical_sector_size": integer,
|
||||
"id_part_entry_disk": string,
|
||||
"minimum_io_size": integer,
|
||||
"physical_sector_size": integer,
|
||||
"logical_sector_size": integer
|
||||
}
|
||||
]
|
||||
|
||||
## 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.
|
||||
|
||||
105
docs/parsers/csv.md
Normal file
105
docs/parsers/csv.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# jc.parsers.csv
|
||||
jc - JSON CLI output utility csv Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --csv as the first argument if the piped input is coming from a csv file.
|
||||
the csv 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.
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
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 -p
|
||||
[
|
||||
{
|
||||
"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(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Each dictionary represents a row in the csv file:
|
||||
|
||||
[
|
||||
{
|
||||
csv file converted to a Dictionary
|
||||
https://docs.python.org/3/library/csv.html
|
||||
}
|
||||
]
|
||||
|
||||
## 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.
|
||||
|
||||
90
docs/parsers/file.md
Normal file
90
docs/parsers/file.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# jc.parsers.file
|
||||
jc - JSON CLI output utility file command Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --file as the first argument if the piped input is coming from file.
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'aix', 'freebsd', 'darwin'
|
||||
|
||||
Examples:
|
||||
|
||||
$ file * | jc --file -p
|
||||
[
|
||||
{
|
||||
"filename": "Applications",
|
||||
"type": "directory"
|
||||
},
|
||||
{
|
||||
"filename": "another file with spaces",
|
||||
"type": "empty"
|
||||
},
|
||||
{
|
||||
"filename": "argstest.py",
|
||||
"type": "Python script text executable, ASCII text"
|
||||
},
|
||||
{
|
||||
"filename": "blkid-p.out",
|
||||
"type": "ASCII text"
|
||||
},
|
||||
{
|
||||
"filename": "blkid-pi.out",
|
||||
"type": "ASCII text, with very long lines"
|
||||
},
|
||||
{
|
||||
"filename": "cd_catalog.xml",
|
||||
"type": "XML 1.0 document text, ASCII text, with CRLF line terminators"
|
||||
},
|
||||
{
|
||||
"filename": "centosserial.sh",
|
||||
"type": "Bourne-Again shell script text executable, UTF-8 Unicode text"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"filename": string,
|
||||
"type ": string
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
141
docs/parsers/group.md
Normal file
141
docs/parsers/group.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# jc.parsers.group
|
||||
jc - JSON CLI output utility /etc/group file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --group as the first argument if the piped input is coming from /etc/group
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/group | jc --group -p
|
||||
[
|
||||
{
|
||||
"group_name": "nobody",
|
||||
"password": "*",
|
||||
"gid": -2,
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "nogroup",
|
||||
"password": "*",
|
||||
"gid": -1,
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "wheel",
|
||||
"password": "*",
|
||||
"gid": 0,
|
||||
"members": [
|
||||
"root"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "certusers",
|
||||
"password": "*",
|
||||
"gid": 29,
|
||||
"members": [
|
||||
"root",
|
||||
"_jabber",
|
||||
"_postfix",
|
||||
"_cyrus",
|
||||
"_calendar",
|
||||
"_dovecot"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ cat /etc/group | jc --group -p -r
|
||||
[
|
||||
{
|
||||
"group_name": "nobody",
|
||||
"password": "*",
|
||||
"gid": "-2",
|
||||
"members": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "nogroup",
|
||||
"password": "*",
|
||||
"gid": "-1",
|
||||
"members": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "wheel",
|
||||
"password": "*",
|
||||
"gid": "0",
|
||||
"members": [
|
||||
"root"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "certusers",
|
||||
"password": "*",
|
||||
"gid": "29",
|
||||
"members": [
|
||||
"root",
|
||||
"_jabber",
|
||||
"_postfix",
|
||||
"_cyrus",
|
||||
"_calendar",
|
||||
"_dovecot"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"group_name": string,
|
||||
"password": string,
|
||||
"gid": integer,
|
||||
"members": [
|
||||
string
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
109
docs/parsers/gshadow.md
Normal file
109
docs/parsers/gshadow.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# jc.parsers.gshadow
|
||||
jc - JSON CLI output utility /etc/gshadow file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --gshadow as the first argument if the piped input is coming from /etc/gshadow
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/gshadow | jc --gshadow -p
|
||||
[
|
||||
{
|
||||
"group_name": "root",
|
||||
"password": "*",
|
||||
"administrators": [],
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "adm",
|
||||
"password": "*",
|
||||
"administrators": [],
|
||||
"members": [
|
||||
"syslog",
|
||||
"joeuser"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ cat /etc/gshadow | jc --gshadow -p -r
|
||||
[
|
||||
{
|
||||
"group_name": "root",
|
||||
"password": "*",
|
||||
"administrators": [
|
||||
""
|
||||
],
|
||||
"members": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "adm",
|
||||
"password": "*",
|
||||
"administrators": [
|
||||
""
|
||||
],
|
||||
"members": [
|
||||
"syslog",
|
||||
"joeuser"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"group_name": string,
|
||||
"password": string,
|
||||
"administrators": [
|
||||
string
|
||||
],
|
||||
"members": [
|
||||
string
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
118
docs/parsers/last.md
Normal file
118
docs/parsers/last.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# jc.parsers.last
|
||||
jc - JSON CLI output utility last Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --last as the first argument if the piped input is coming from last or lastb
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ last | jc --last -p
|
||||
[
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys002",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 14:31",
|
||||
"logout": "still logged in"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 10:38",
|
||||
"logout": "10:38",
|
||||
"duration": "00:00"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 10:18",
|
||||
"logout": "10:18",
|
||||
"duration": "00:00"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ last | jc --last -p -r
|
||||
[
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys002",
|
||||
"hostname": "-",
|
||||
"login": "Thu Feb 27 14:31",
|
||||
"logout": "still_logged_in"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": "-",
|
||||
"login": "Thu Feb 27 10:38",
|
||||
"logout": "10:38",
|
||||
"duration": "00:00"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": "-",
|
||||
"login": "Thu Feb 27 10:18",
|
||||
"logout": "10:18",
|
||||
"duration": "00:00"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"user": string,
|
||||
"tty": string,
|
||||
"hostname": string,
|
||||
"login": string,
|
||||
"logout": string,
|
||||
"duration": string
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
# jc.parsers.ls
|
||||
jc - JSON CLI output utility ls Parser
|
||||
|
||||
Note: The -l or -b option of ls should be used to correctly parse filenames that include newline characters.
|
||||
Since ls does not encode newlines in filenames when outputting to a pipe it will cause jc to see
|
||||
multiple files instead of a single file if -l or -b is not used.
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ls as the first argument if the piped input is coming from ls
|
||||
|
||||
ls options supported:
|
||||
- None
|
||||
- la
|
||||
- h file sizes will be available in text form with -r but larger file sizes
|
||||
with human readable suffixes will be converted to Null in default view
|
||||
since the parser attempts to convert this field to an integer.
|
||||
|
||||
-lbaR
|
||||
--time-style=full-iso
|
||||
-h file sizes will be available in text form with -r but larger file sizes
|
||||
with human readable suffixes will be converted to Null in default view
|
||||
since the parser attempts to convert this field to an integer.
|
||||
|
||||
Compatibility:
|
||||
|
||||
@@ -165,6 +170,7 @@ Returns:
|
||||
"filename": string,
|
||||
"flags": string,
|
||||
"links": integer,
|
||||
"parent": string,
|
||||
"owner": string,
|
||||
"group": string,
|
||||
"size": integer,
|
||||
|
||||
235
docs/parsers/ntpq.md
Normal file
235
docs/parsers/ntpq.md
Normal file
@@ -0,0 +1,235 @@
|
||||
# jc.parsers.ntpq
|
||||
jc - JSON CLI output utility ntpq Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ntpq as the first argument if the piped input is coming from ntpq -p
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ ntpq -p | jc --ntpq -p
|
||||
[
|
||||
{
|
||||
"remote": "44.190.6.254",
|
||||
"refid": "127.67.113.92",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": 1,
|
||||
"poll": 64,
|
||||
"reach": 1,
|
||||
"delay": 23.399,
|
||||
"offset": -2.805,
|
||||
"jitter": 2.131,
|
||||
"state": null
|
||||
},
|
||||
{
|
||||
"remote": "ntp.wdc1.us.lea",
|
||||
"refid": "130.133.1.10",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": null,
|
||||
"poll": 64,
|
||||
"reach": 1,
|
||||
"delay": 93.053,
|
||||
"offset": -0.807,
|
||||
"jitter": 2.839,
|
||||
"state": null
|
||||
},
|
||||
{
|
||||
"remote": "clock.team-cymr",
|
||||
"refid": "204.9.54.119",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": null,
|
||||
"poll": 64,
|
||||
"reach": 1,
|
||||
"delay": 70.337,
|
||||
"offset": -2.909,
|
||||
"jitter": 2.6,
|
||||
"state": null
|
||||
},
|
||||
{
|
||||
"remote": "mirror1.sjc02.s",
|
||||
"refid": "216.218.254.202",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": 2,
|
||||
"poll": 64,
|
||||
"reach": 1,
|
||||
"delay": 29.325,
|
||||
"offset": 1.044,
|
||||
"jitter": 4.069,
|
||||
"state": null,
|
||||
}
|
||||
]
|
||||
|
||||
$ ntpq -pn| jc --ntpq -p
|
||||
[
|
||||
{
|
||||
"remote": "44.190.6.254",
|
||||
"refid": "127.67.113.92",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": 66,
|
||||
"poll": 64,
|
||||
"reach": 377,
|
||||
"delay": 22.69,
|
||||
"offset": -0.392,
|
||||
"jitter": 2.085,
|
||||
"state": "+"
|
||||
},
|
||||
{
|
||||
"remote": "108.59.2.24",
|
||||
"refid": "130.133.1.10",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": 63,
|
||||
"poll": 64,
|
||||
"reach": 377,
|
||||
"delay": 90.805,
|
||||
"offset": 2.84,
|
||||
"jitter": 1.908,
|
||||
"state": "-"
|
||||
},
|
||||
{
|
||||
"remote": "38.229.71.1",
|
||||
"refid": "204.9.54.119",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": 64,
|
||||
"poll": 64,
|
||||
"reach": 377,
|
||||
"delay": 68.699,
|
||||
"offset": -0.61,
|
||||
"jitter": 2.576,
|
||||
"state": "+"
|
||||
},
|
||||
{
|
||||
"remote": "72.5.72.15",
|
||||
"refid": "216.218.254.202",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": 63,
|
||||
"poll": 64,
|
||||
"reach": 377,
|
||||
"delay": 22.654,
|
||||
"offset": 0.231,
|
||||
"jitter": 1.964,
|
||||
"state": "*"
|
||||
}
|
||||
]
|
||||
|
||||
$ ntpq -pn| jc --ntpq -p -r
|
||||
[
|
||||
{
|
||||
"s": "+",
|
||||
"remote": "44.190.6.254",
|
||||
"refid": "127.67.113.92",
|
||||
"st": "2",
|
||||
"t": "u",
|
||||
"when": "66",
|
||||
"poll": "64",
|
||||
"reach": "377",
|
||||
"delay": "22.690",
|
||||
"offset": "-0.392",
|
||||
"jitter": "2.085"
|
||||
},
|
||||
{
|
||||
"s": "-",
|
||||
"remote": "108.59.2.24",
|
||||
"refid": "130.133.1.10",
|
||||
"st": "2",
|
||||
"t": "u",
|
||||
"when": "63",
|
||||
"poll": "64",
|
||||
"reach": "377",
|
||||
"delay": "90.805",
|
||||
"offset": "2.840",
|
||||
"jitter": "1.908"
|
||||
},
|
||||
{
|
||||
"s": "+",
|
||||
"remote": "38.229.71.1",
|
||||
"refid": "204.9.54.119",
|
||||
"st": "2",
|
||||
"t": "u",
|
||||
"when": "64",
|
||||
"poll": "64",
|
||||
"reach": "377",
|
||||
"delay": "68.699",
|
||||
"offset": "-0.610",
|
||||
"jitter": "2.576"
|
||||
},
|
||||
{
|
||||
"s": "*",
|
||||
"remote": "72.5.72.15",
|
||||
"refid": "216.218.254.202",
|
||||
"st": "2",
|
||||
"t": "u",
|
||||
"when": "63",
|
||||
"poll": "64",
|
||||
"reach": "377",
|
||||
"delay": "22.654",
|
||||
"offset": "0.231",
|
||||
"jitter": "1.964"
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"state": string, # space/~ converted to null
|
||||
"remote": string,
|
||||
"refid": string,
|
||||
"st": integer,
|
||||
"t": string,
|
||||
"when": integer, # - converted to null
|
||||
"poll": integer,
|
||||
"reach": integer,
|
||||
"delay": float,
|
||||
"offset": float,
|
||||
"jitter": float
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
126
docs/parsers/passwd.md
Normal file
126
docs/parsers/passwd.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# jc.parsers.passwd
|
||||
jc - JSON CLI output utility /etc/passwd file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --passwd as the first argument if the piped input is coming from /etc/passwd
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/passwd | jc --passwd -p
|
||||
[
|
||||
{
|
||||
"username": "nobody",
|
||||
"password": "*",
|
||||
"uid": -2,
|
||||
"gid": -2,
|
||||
"comment": "Unprivileged User",
|
||||
"home": "/var/empty",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"comment": "System Administrator",
|
||||
"home": "/var/root",
|
||||
"shell": "/bin/sh"
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"uid": 1,
|
||||
"gid": 1,
|
||||
"comment": "System Services",
|
||||
"home": "/var/root",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ cat /etc/passwd | jc --passwd -p -r
|
||||
[
|
||||
{
|
||||
"username": "nobody",
|
||||
"password": "*",
|
||||
"uid": "-2",
|
||||
"gid": "-2",
|
||||
"comment": "Unprivileged User",
|
||||
"home": "/var/empty",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"uid": "0",
|
||||
"gid": "0",
|
||||
"comment": "System Administrator",
|
||||
"home": "/var/root",
|
||||
"shell": "/bin/sh"
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"uid": "1",
|
||||
"gid": "1",
|
||||
"comment": "System Services",
|
||||
"home": "/var/root",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"username": string,
|
||||
"password": string,
|
||||
"uid": integer,
|
||||
"gid": integer,
|
||||
"comment": string,
|
||||
"home": string,
|
||||
"shell": string
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
133
docs/parsers/shadow.md
Normal file
133
docs/parsers/shadow.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# jc.parsers.shadow
|
||||
jc - JSON CLI output utility /etc/shadow file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --shadow as the first argument if the piped input is coming from /etc/shadow
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ sudo cat /etc/shadow | jc --shadow -p
|
||||
[
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
{
|
||||
"username": "bin",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ sudo cat /etc/shadow | jc --shadow -p -r
|
||||
[
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"last_changed": "18113",
|
||||
"minimum": "0",
|
||||
"maximum": "99999",
|
||||
"warn": "7",
|
||||
"inactive": "",
|
||||
"expire": ""
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"last_changed": "18113",
|
||||
"minimum": "0",
|
||||
"maximum": "99999",
|
||||
"warn": "7",
|
||||
"inactive": "",
|
||||
"expire": ""
|
||||
},
|
||||
{
|
||||
"username": "bin",
|
||||
"password": "*",
|
||||
"last_changed": "18113",
|
||||
"minimum": "0",
|
||||
"maximum": "99999",
|
||||
"warn": "7",
|
||||
"inactive": "",
|
||||
"expire": ""
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"username": string,
|
||||
"password": string,
|
||||
"last_changed": integer,
|
||||
"minimum": integer,
|
||||
"maximum": integer,
|
||||
"warn": integer,
|
||||
"inactive": integer,
|
||||
"expire": integer
|
||||
}
|
||||
]
|
||||
|
||||
## 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.
|
||||
|
||||
87
docs/parsers/timedatectl.md
Normal file
87
docs/parsers/timedatectl.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# jc.parsers.timedatectl
|
||||
jc - JSON CLI output utility timedatectl Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --timedatectl as the first argument if the piped input is coming from timedatectl or timedatectl status
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ timedatectl | jc --timedatectl -p
|
||||
{
|
||||
"local_time": "Tue 2020-03-10 17:53:21 PDT",
|
||||
"universal_time": "Wed 2020-03-11 00:53:21 UTC",
|
||||
"rtc_time": "Wed 2020-03-11 00:53:21",
|
||||
"time_zone": "America/Los_Angeles (PDT, -0700)",
|
||||
"ntp_enabled": true,
|
||||
"ntp_synchronized": true,
|
||||
"rtc_in_local_tz": false,
|
||||
"dst_active": true
|
||||
}
|
||||
|
||||
$ timedatectl | jc --timedatectl -p -r
|
||||
{
|
||||
"local_time": "Tue 2020-03-10 17:53:21 PDT",
|
||||
"universal_time": "Wed 2020-03-11 00:53:21 UTC",
|
||||
"rtc_time": "Wed 2020-03-11 00:53:21",
|
||||
"time_zone": "America/Los_Angeles (PDT, -0700)",
|
||||
"ntp_enabled": "yes",
|
||||
"ntp_synchronized": "yes",
|
||||
"rtc_in_local_tz": "no",
|
||||
"dst_active": "yes"
|
||||
}
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Structured data with the following schema:
|
||||
|
||||
{
|
||||
"local_time": string,
|
||||
"universal_time": string,
|
||||
"rtc_time": string,
|
||||
"time_zone": string,
|
||||
"ntp_enabled": boolean,
|
||||
"ntp_synchronized": boolean,
|
||||
"system_clock_synchronized": boolean,
|
||||
"systemd-timesyncd.service_active": boolean,
|
||||
"rtc_in_local_tz": boolean,
|
||||
"dst_active": boolean
|
||||
}
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
|
||||
152
docs/parsers/who.md
Normal file
152
docs/parsers/who.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# jc.parsers.who
|
||||
jc - JSON CLI output utility who Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --who as the first argument if the piped input is coming from who
|
||||
|
||||
accepts any of the following who options (or no options): -aTH
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ who -a | jc --who -p
|
||||
[
|
||||
{
|
||||
"event": "reboot",
|
||||
"time": "Feb 7 23:31",
|
||||
"pid": 1
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "-",
|
||||
"tty": "console",
|
||||
"time": "Feb 7 23:32",
|
||||
"idle": "old",
|
||||
"pid": 105
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys000",
|
||||
"time": "Feb 13 16:44",
|
||||
"idle": ".",
|
||||
"pid": 51217,
|
||||
"comment": "term=0 exit=0"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "?",
|
||||
"tty": "ttys003",
|
||||
"time": "Feb 28 08:59",
|
||||
"idle": "01:36",
|
||||
"pid": 41402
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys004",
|
||||
"time": "Mar 1 16:35",
|
||||
"idle": ".",
|
||||
"pid": 15679,
|
||||
"from": "192.168.1.5"
|
||||
}
|
||||
]
|
||||
|
||||
$ who -a | jc --who -p -r
|
||||
[
|
||||
{
|
||||
"event": "reboot",
|
||||
"time": "Feb 7 23:31",
|
||||
"pid": "1"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "-",
|
||||
"tty": "console",
|
||||
"time": "Feb 7 23:32",
|
||||
"idle": "old",
|
||||
"pid": "105"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys000",
|
||||
"time": "Feb 13 16:44",
|
||||
"idle": ".",
|
||||
"pid": "51217",
|
||||
"comment": "term=0 exit=0"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "?",
|
||||
"tty": "ttys003",
|
||||
"time": "Feb 28 08:59",
|
||||
"idle": "01:36",
|
||||
"pid": "41402"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys004",
|
||||
"time": "Mar 1 16:35",
|
||||
"idle": ".",
|
||||
"pid": "15679",
|
||||
"from": "192.168.1.5"
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"user": string,
|
||||
"event": string,
|
||||
"writeable_tty": string,
|
||||
"tty": string,
|
||||
"time": string,
|
||||
"idle": string,
|
||||
"pid": integer,
|
||||
"from": string,
|
||||
"comment": string
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
160
jc/cli.py
160
jc/cli.py
@@ -13,7 +13,7 @@ import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.7.3'
|
||||
version = '1.9.0'
|
||||
description = 'jc cli output JSON conversion tool'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
@@ -22,15 +22,22 @@ class info():
|
||||
__version__ = info.version
|
||||
|
||||
parsers = [
|
||||
'airport',
|
||||
'airport-s',
|
||||
'arp',
|
||||
'blkid',
|
||||
'crontab',
|
||||
'crontab-u',
|
||||
'csv',
|
||||
'df',
|
||||
'dig',
|
||||
'du',
|
||||
'env',
|
||||
'file',
|
||||
'free',
|
||||
'fstab',
|
||||
'group',
|
||||
'gshadow',
|
||||
'history',
|
||||
'hosts',
|
||||
'id',
|
||||
@@ -38,25 +45,31 @@ parsers = [
|
||||
'ini',
|
||||
'iptables',
|
||||
'jobs',
|
||||
'last',
|
||||
'ls',
|
||||
'lsblk',
|
||||
'lsmod',
|
||||
'lsof',
|
||||
'mount',
|
||||
'netstat',
|
||||
'ntpq',
|
||||
'passwd',
|
||||
'pip-list',
|
||||
'pip-show',
|
||||
'ps',
|
||||
'route',
|
||||
'shadow',
|
||||
'ss',
|
||||
'stat',
|
||||
'systemctl',
|
||||
'systemctl-lj',
|
||||
'systemctl-ls',
|
||||
'systemctl-luf',
|
||||
'timedatectl',
|
||||
'uname',
|
||||
'uptime',
|
||||
'w',
|
||||
'who',
|
||||
'xml',
|
||||
'yaml'
|
||||
]
|
||||
@@ -145,10 +158,6 @@ def helptext(message):
|
||||
|
||||
Usage: COMMAND | jc PARSER [OPTIONS]
|
||||
|
||||
or
|
||||
|
||||
COMMAND | jc [OPTIONS] PARSER
|
||||
|
||||
or magic syntax:
|
||||
|
||||
jc [OPTIONS] COMMAND
|
||||
@@ -179,68 +188,72 @@ def json_out(data, pretty=False):
|
||||
print(json.dumps(data))
|
||||
|
||||
|
||||
def magic():
|
||||
"""Parse with magic syntax: jc -p ls -al"""
|
||||
if len(sys.argv) > 1 and not sys.argv[1].startswith('--'):
|
||||
parser_info = about_jc()['parsers']
|
||||
# correctly parse escape characters and spaces with shlex
|
||||
args_given = " ".join(map(shlex.quote, sys.argv[1:])).split()
|
||||
options = []
|
||||
found_parser = None
|
||||
def generate_magic_command(args):
|
||||
"""
|
||||
Returns a tuple with a boolean and a command, where the boolean signifies that
|
||||
the command is valid, and the command is either a command string or None.
|
||||
"""
|
||||
|
||||
# find the options
|
||||
if args_given[0].startswith('-'):
|
||||
p = 0
|
||||
for i, arg in list(enumerate(args_given)):
|
||||
# parser found - use standard syntax
|
||||
if arg.startswith('--'):
|
||||
return
|
||||
# option found - populate option list
|
||||
elif arg.startswith('-'):
|
||||
options.append(args_given.pop(i - p)[1:])
|
||||
p = p + 1
|
||||
# command found if iterator didn't already stop - stop iterating
|
||||
else:
|
||||
break
|
||||
# Parse with magic syntax: jc -p ls -al
|
||||
if len(args) <= 1 or args[1].startswith('--'):
|
||||
return False, None
|
||||
|
||||
# find the command and parser
|
||||
for parser in parser_info:
|
||||
if 'magic_commands' in parser:
|
||||
# first pass for two word commands: e.g. 'pip list'
|
||||
for magic_command in parser['magic_commands']:
|
||||
try:
|
||||
if ' '.join(args_given[0:2]) == magic_command:
|
||||
found_parser = parser['argument']
|
||||
break
|
||||
# No command found - go to next loop (for cases like 'jc -a')
|
||||
except Exception:
|
||||
break
|
||||
# correctly parse escape characters and spaces with shlex
|
||||
args_given = ' '.join(map(shlex.quote, args[1:])).split()
|
||||
options = []
|
||||
|
||||
# second pass for one word commands: e.g. 'ls'
|
||||
if not found_parser:
|
||||
for magic_command in parser['magic_commands']:
|
||||
try:
|
||||
if args_given[0] == magic_command:
|
||||
found_parser = parser['argument']
|
||||
break
|
||||
# No command found - use standard syntax (for cases like 'jc -a')
|
||||
except Exception:
|
||||
return
|
||||
# find the options
|
||||
for arg in list(args_given):
|
||||
# parser found - use standard syntax
|
||||
if arg.startswith('--'):
|
||||
return False, None
|
||||
|
||||
# construct a new command line using the standard syntax: COMMAND | jc --PARSER -OPTIONS
|
||||
run_command = ' '.join(args_given)
|
||||
if found_parser:
|
||||
if options:
|
||||
cmd_options = '-' + ''.join(options)
|
||||
else:
|
||||
cmd_options = ''
|
||||
whole_command = ' '.join([run_command, '|', 'jc', found_parser, cmd_options])
|
||||
# option found - populate option list
|
||||
elif arg.startswith('-'):
|
||||
options.extend(args_given.pop(0)[1:])
|
||||
|
||||
os.system(whole_command)
|
||||
exit()
|
||||
# command found if iterator didn't already stop - stop iterating
|
||||
else:
|
||||
helptext(f'parser not found for "{run_command}"')
|
||||
sys.exit(1)
|
||||
break
|
||||
|
||||
# all options popped and no command found - for case like 'jc -a'
|
||||
if len(args_given) == 0:
|
||||
return False, None
|
||||
|
||||
magic_dict = {}
|
||||
parser_info = about_jc()['parsers']
|
||||
|
||||
# Create a dictionary of magic_commands to their respective parsers.
|
||||
for entry in parser_info:
|
||||
# Update the dict with all of the magic commands for this parser, if they exist.
|
||||
magic_dict.update({mc: entry['argument'] for mc in entry.get('magic_commands', [])})
|
||||
|
||||
# find the command and parser
|
||||
one_word_command = args_given[0]
|
||||
two_word_command = ' '.join(args_given[0:2])
|
||||
|
||||
# Try to get a parser for two_word_command, otherwise get one for one_word_command
|
||||
found_parser = magic_dict.get(two_word_command, magic_dict.get(one_word_command))
|
||||
|
||||
# construct a new command line using the standard syntax: COMMAND | jc --PARSER -OPTIONS
|
||||
run_command = ' '.join(args_given)
|
||||
if found_parser:
|
||||
cmd_options = ('-' + ''.join(options)) if options else ''
|
||||
return True, ' '.join([run_command, '|', 'jc', found_parser, cmd_options])
|
||||
else:
|
||||
return False, run_command
|
||||
|
||||
|
||||
def magic():
|
||||
valid_command, run_command = generate_magic_command(sys.argv)
|
||||
if valid_command:
|
||||
os.system(run_command)
|
||||
exit()
|
||||
elif run_command is None:
|
||||
return
|
||||
else:
|
||||
helptext(f'parser not found for "{run_command}"')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
@@ -251,28 +264,16 @@ def main():
|
||||
magic()
|
||||
|
||||
options = []
|
||||
debug = False
|
||||
pretty = False
|
||||
quiet = False
|
||||
raw = False
|
||||
|
||||
# options
|
||||
for opt in sys.argv:
|
||||
if opt.startswith('-') and not opt.startswith('--'):
|
||||
for flag in opt[1:]:
|
||||
options.append(flag)
|
||||
options.extend(opt[1:])
|
||||
|
||||
if 'd' in options:
|
||||
debug = True
|
||||
|
||||
if 'p' in options:
|
||||
pretty = True
|
||||
|
||||
if 'q' in options:
|
||||
quiet = True
|
||||
|
||||
if 'r' in options:
|
||||
raw = True
|
||||
debug = 'd' in options
|
||||
pretty = 'p' in options
|
||||
quiet = 'q' in options
|
||||
raw = 'r' in options
|
||||
|
||||
if 'a' in options:
|
||||
json_out(about_jc(), pretty=pretty)
|
||||
@@ -308,7 +309,8 @@ def main():
|
||||
found = True
|
||||
break
|
||||
except Exception:
|
||||
jc.utils.error_message(f'{parser_name} parser could not parse the input data. Did you use the correct parser?\n For details use the -d option.')
|
||||
jc.utils.error_message(
|
||||
f'{parser_name} parser could not parse the input data. Did you use the correct parser?\n For details use the -d option.')
|
||||
sys.exit(1)
|
||||
|
||||
if not found:
|
||||
|
||||
141
jc/parsers/airport.py
Normal file
141
jc/parsers/airport.py
Normal file
@@ -0,0 +1,141 @@
|
||||
"""jc - JSON CLI output utility airport -I Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --airport as the first argument if the piped input is coming from airport -I (OSX)
|
||||
|
||||
This program can be found at:
|
||||
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport
|
||||
|
||||
Compatibility:
|
||||
|
||||
'darwin'
|
||||
|
||||
Examples:
|
||||
|
||||
$ airport -I | jc --airport -p
|
||||
{
|
||||
"agrctlrssi": -66,
|
||||
"agrextrssi": 0,
|
||||
"agrctlnoise": -90,
|
||||
"agrextnoise": 0,
|
||||
"state": "running",
|
||||
"op_mode": "station",
|
||||
"lasttxrate": 195,
|
||||
"maxrate": 867,
|
||||
"lastassocstatus": 0,
|
||||
"802_11_auth": "open",
|
||||
"link_auth": "wpa2-psk",
|
||||
"bssid": "3c:37:86:15:ad:f9",
|
||||
"ssid": "SnazzleDazzle",
|
||||
"mcs": 0,
|
||||
"channel": "48,80"
|
||||
}
|
||||
|
||||
$ airport -I | jc --airport -p -r
|
||||
{
|
||||
"agrctlrssi": "-66",
|
||||
"agrextrssi": "0",
|
||||
"agrctlnoise": "-90",
|
||||
"agrextnoise": "0",
|
||||
"state": "running",
|
||||
"op_mode": "station",
|
||||
"lasttxrate": "195",
|
||||
"maxrate": "867",
|
||||
"lastassocstatus": "0",
|
||||
"802_11_auth": "open",
|
||||
"link_auth": "wpa2-psk",
|
||||
"bssid": "3c:37:86:15:ad:f9",
|
||||
"ssid": "SnazzleDazzle",
|
||||
"mcs": "0",
|
||||
"channel": "48,80"
|
||||
}
|
||||
"""
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'airport -I command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['darwin']
|
||||
magic_commands = ['airport -I']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Structured data with the following schema:
|
||||
|
||||
{
|
||||
"agrctlrssi": integer,
|
||||
"agrextrssi": integer,
|
||||
"agrctlnoise": integer,
|
||||
"agrextnoise": integer,
|
||||
"state": string,
|
||||
"op_mode": string,
|
||||
"lasttxrate": integer,
|
||||
"maxrate": integer,
|
||||
"lastassocstatus": integer,
|
||||
"802_11_auth": string,
|
||||
"link_auth": string,
|
||||
"bssid": string,
|
||||
"ssid": string,
|
||||
"mcs": integer,
|
||||
"channel": string
|
||||
}
|
||||
"""
|
||||
# integer changes
|
||||
int_list = ['agrctlrssi', 'agrextrssi', 'agrctlnoise', 'agrextnoise',
|
||||
'lasttxrate', 'maxrate', 'lastassocstatus', 'mcs']
|
||||
for key in proc_data:
|
||||
if key in int_list:
|
||||
try:
|
||||
proc_data[key] = int(proc_data[key])
|
||||
except (ValueError):
|
||||
proc_data[key] = None
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = {}
|
||||
|
||||
for line in filter(None, data.splitlines()):
|
||||
linedata = line.split(':', maxsplit=1)
|
||||
raw_output[linedata[0].strip().lower().replace(' ', '_').replace('.', '_')] = linedata[1].strip()
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
186
jc/parsers/airport_s.py
Normal file
186
jc/parsers/airport_s.py
Normal file
@@ -0,0 +1,186 @@
|
||||
"""jc - JSON CLI output utility airport -s Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --airport as the first argument if the piped input is coming from airport -s (OSX)
|
||||
|
||||
This program can be found at:
|
||||
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport
|
||||
|
||||
Compatibility:
|
||||
|
||||
'darwin'
|
||||
|
||||
Examples:
|
||||
|
||||
$ airport -s | jc --airport-s -p
|
||||
[
|
||||
{
|
||||
"ssid": "DIRECT-4A-HP OfficeJet 3830",
|
||||
"bssid": "00:67:eb:2a:a7:3b",
|
||||
"rssi": -90,
|
||||
"channel": "6",
|
||||
"ht": true,
|
||||
"cc": "--",
|
||||
"security": [
|
||||
"WPA2(PSK/AES/AES)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ssid": "Latitude38",
|
||||
"bssid": "c0:ff:d5:d2:7a:f3",
|
||||
"rssi": -85,
|
||||
"channel": "11",
|
||||
"ht": true,
|
||||
"cc": "US",
|
||||
"security": [
|
||||
"WPA2(PSK/AES/AES)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ssid": "xfinitywifi",
|
||||
"bssid": "6e:e3:0e:b8:45:99",
|
||||
"rssi": -83,
|
||||
"channel": "11",
|
||||
"ht": true,
|
||||
"cc": "US",
|
||||
"security": [
|
||||
"NONE"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ airport -s | jc --airport -p -r
|
||||
[
|
||||
{
|
||||
"ssid": "DIRECT-F3-HP ENVY 5660 series",
|
||||
"bssid": "b0:5a:da:6f:0a:d4",
|
||||
"rssi": "-93",
|
||||
"channel": "1",
|
||||
"ht": "Y",
|
||||
"cc": "--",
|
||||
"security": "WPA2(PSK/AES/AES)"
|
||||
},
|
||||
{
|
||||
"ssid": "YouAreInfected-5",
|
||||
"bssid": "5c:e3:0e:c2:85:da",
|
||||
"rssi": "-85",
|
||||
"channel": "36",
|
||||
"ht": "Y",
|
||||
"cc": "US",
|
||||
"security": "WPA(PSK/AES,TKIP/TKIP) WPA2(PSK/AES,TKIP/TKIP)"
|
||||
},
|
||||
{
|
||||
"ssid": "YuanFamily",
|
||||
"bssid": "5c:e3:0e:b8:5f:9a",
|
||||
"rssi": "-84",
|
||||
"channel": "11",
|
||||
"ht": "Y",
|
||||
"cc": "US",
|
||||
"security": "WPA(PSK/AES,TKIP/TKIP) WPA2(PSK/AES,TKIP/TKIP)"
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
import jc.parsers.universal
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'airport -s command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['darwin']
|
||||
magic_commands = ['airport -s']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
[
|
||||
{
|
||||
"ssid": string,
|
||||
"bssid": string,
|
||||
"rssi": integer,
|
||||
"channel": string,
|
||||
"ht": boolean,
|
||||
"cc": string,
|
||||
"security": [
|
||||
string,
|
||||
]
|
||||
}
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
|
||||
# integers
|
||||
int_list = ['rssi']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
entry[key] = int(entry[key])
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
# booleans
|
||||
bool_list = ['ht']
|
||||
for key in entry:
|
||||
if key in bool_list:
|
||||
try:
|
||||
entry[key] = True if entry[key] == 'Y' else False
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
if 'security' in entry:
|
||||
entry['security'] = entry['security'].split()
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# fix headers
|
||||
cleandata[0] = cleandata[0].lower()
|
||||
cleandata[0] = cleandata[0].replace('-', '_')
|
||||
cleandata[0] = cleandata[0].replace('security (auth/unicast/group)', 'security')
|
||||
|
||||
# parse the data
|
||||
raw_output = jc.parsers.universal.sparse_table_parse(cleandata)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
@@ -196,12 +196,13 @@ def parse(data, raw=False, quiet=False):
|
||||
raw_output = []
|
||||
for line in cleandata:
|
||||
line = line.split()
|
||||
output_line = {}
|
||||
output_line['name'] = line[0]
|
||||
output_line['address'] = line[1].lstrip('(').rstrip(')')
|
||||
output_line['hwtype'] = line[4].lstrip('[').rstrip(']')
|
||||
output_line['hwaddress'] = line[3]
|
||||
output_line['iface'] = line[6]
|
||||
output_line = {
|
||||
'name': line[0],
|
||||
'address': line[1].lstrip('(').rstrip(')'),
|
||||
'hwtype': line[4].lstrip('[').rstrip(']'),
|
||||
'hwaddress': line[3],
|
||||
'iface': line[6],
|
||||
}
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
|
||||
218
jc/parsers/blkid.py
Normal file
218
jc/parsers/blkid.py
Normal file
@@ -0,0 +1,218 @@
|
||||
"""jc - JSON CLI output utility blkid Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --blkid as the first argument if the piped input is coming from blkid
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ blkid | jc --blkid -p
|
||||
[
|
||||
{
|
||||
"device": "/dev/sda1",
|
||||
"uuid": "05d927ab-5875-49e4-ada1-7f46cb32c932",
|
||||
"type": "xfs"
|
||||
},
|
||||
{
|
||||
"device": "/dev/sda2",
|
||||
"uuid": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"type": "LVM2_member"
|
||||
},
|
||||
{
|
||||
"device": "/dev/mapper/centos-root",
|
||||
"uuid": "07d718ff-950c-4e5b-98f0-42a1147c77d9",
|
||||
"type": "xfs"
|
||||
},
|
||||
{
|
||||
"device": "/dev/mapper/centos-swap",
|
||||
"uuid": "615eb89a-bcbf-46fd-80e3-c483ff5c931f",
|
||||
"type": "swap"
|
||||
}
|
||||
]
|
||||
|
||||
$ sudo blkid -o udev -ip /dev/sda2 | jc --blkid -p
|
||||
[
|
||||
{
|
||||
"id_fs_uuid": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"id_fs_uuid_enc": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"id_fs_version": "LVM2\\x20001",
|
||||
"id_fs_type": "LVM2_member",
|
||||
"id_fs_usage": "raid",
|
||||
"id_iolimit_minimum_io_size": 512,
|
||||
"id_iolimit_physical_sector_size": 512,
|
||||
"id_iolimit_logical_sector_size": 512,
|
||||
"id_part_entry_scheme": "dos",
|
||||
"id_part_entry_type": "0x8e",
|
||||
"id_part_entry_number": 2,
|
||||
"id_part_entry_offset": 2099200,
|
||||
"id_part_entry_size": 39843840,
|
||||
"id_part_entry_disk": "8:0"
|
||||
}
|
||||
]
|
||||
|
||||
$ sudo blkid -ip /dev/sda1 | jc --blkid -p -r
|
||||
[
|
||||
{
|
||||
"devname": "/dev/sda1",
|
||||
"uuid": "05d927bb-5875-49e3-ada1-7f46cb31c932",
|
||||
"type": "xfs",
|
||||
"usage": "filesystem",
|
||||
"minimum_io_size": "512",
|
||||
"physical_sector_size": "512",
|
||||
"logical_sector_size": "512",
|
||||
"part_entry_scheme": "dos",
|
||||
"part_entry_type": "0x83",
|
||||
"part_entry_flags": "0x80",
|
||||
"part_entry_number": "1",
|
||||
"part_entry_offset": "2048",
|
||||
"part_entry_size": "2097152",
|
||||
"part_entry_disk": "8:0"
|
||||
}
|
||||
]
|
||||
"""
|
||||
import shlex
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'blkid command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['blkid']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"device": string,
|
||||
"uuid": string,
|
||||
"type": string,
|
||||
"usage": string,
|
||||
"part_entry_scheme": string,
|
||||
"part_entry_type": string,
|
||||
"part_entry_flags": string,
|
||||
"part_entry_number": integer,
|
||||
"part_entry_offset": integer,
|
||||
"part_entry_size": integer,
|
||||
"part_entry_disk": string,
|
||||
"id_fs_uuid": string,
|
||||
"id_fs_uuid_enc": string,
|
||||
"id_fs_version": string,
|
||||
"id_fs_type": string,
|
||||
"id_fs_usage": string,
|
||||
"id_part_entry_scheme": string,
|
||||
"id_part_entry_type": string,
|
||||
"id_part_entry_flags": string,
|
||||
"id_part_entry_number": integer,
|
||||
"id_part_entry_offset": integer,
|
||||
"id_part_entry_size": integer,
|
||||
"id_iolimit_minimum_io_size": integer,
|
||||
"id_iolimit_physical_sector_size": integer,
|
||||
"id_iolimit_logical_sector_size": integer,
|
||||
"id_part_entry_disk": string,
|
||||
"minimum_io_size": integer,
|
||||
"physical_sector_size": integer,
|
||||
"logical_sector_size": integer
|
||||
}
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
if 'devname' in entry:
|
||||
entry['device'] = entry.pop('devname')
|
||||
|
||||
int_list = ['part_entry_number', 'part_entry_offset', 'part_entry_size', 'id_part_entry_number',
|
||||
'id_part_entry_offset', 'id_part_entry_size', 'minimum_io_size', 'physical_sector_size',
|
||||
'logical_sector_size', 'id_iolimit_minimum_io_size', 'id_iolimit_physical_sector_size',
|
||||
'id_iolimit_logical_sector_size']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
entry[key] = int(entry[key])
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
|
||||
if data:
|
||||
# if the first field is a device, use normal parsing:
|
||||
if data.split(maxsplit=1)[0][-1] == ':':
|
||||
linedata = data.splitlines()
|
||||
|
||||
for line in linedata:
|
||||
output_line = {}
|
||||
entries = shlex.split(line)
|
||||
output_line['device'] = entries.pop(0)[:-1]
|
||||
|
||||
for entry in entries:
|
||||
key = entry.split('=', maxsplit=1)[0].lower()
|
||||
value = entry.split('=', maxsplit=1)[1]
|
||||
output_line[key] = value
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
# else use key/value per line parsing
|
||||
else:
|
||||
linedata = data.splitlines()
|
||||
output_line = {}
|
||||
for line in linedata:
|
||||
if line == '':
|
||||
if output_line:
|
||||
raw_output.append(output_line)
|
||||
output_line = {}
|
||||
continue
|
||||
continue
|
||||
|
||||
key = line.split('=', maxsplit=1)[0].lower()
|
||||
value = line.split('=', maxsplit=1)[1]
|
||||
output_line[key] = value
|
||||
|
||||
if output_line:
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
141
jc/parsers/csv.py
Normal file
141
jc/parsers/csv.py
Normal file
@@ -0,0 +1,141 @@
|
||||
"""jc - JSON CLI output utility csv Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --csv as the first argument if the piped input is coming from a csv file.
|
||||
the csv 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.
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
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 -p
|
||||
[
|
||||
{
|
||||
"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"
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
import csv
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'CSV file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
details = 'Using the python standard csv library'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Each dictionary represents a row in the csv file:
|
||||
|
||||
[
|
||||
{
|
||||
csv file converted to a Dictionary
|
||||
https://docs.python.org/3/library/csv.html
|
||||
}
|
||||
]
|
||||
"""
|
||||
|
||||
# No further processing
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
dialect = None
|
||||
try:
|
||||
dialect = csv.Sniffer().sniff(data[:1024])
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
reader = csv.DictReader(cleandata, dialect=dialect)
|
||||
|
||||
for row in reader:
|
||||
raw_output.append(row)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
128
jc/parsers/file.py
Normal file
128
jc/parsers/file.py
Normal file
@@ -0,0 +1,128 @@
|
||||
"""jc - JSON CLI output utility file command Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --file as the first argument if the piped input is coming from file.
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'aix', 'freebsd', 'darwin'
|
||||
|
||||
Examples:
|
||||
|
||||
$ file * | jc --file -p
|
||||
[
|
||||
{
|
||||
"filename": "Applications",
|
||||
"type": "directory"
|
||||
},
|
||||
{
|
||||
"filename": "another file with spaces",
|
||||
"type": "empty"
|
||||
},
|
||||
{
|
||||
"filename": "argstest.py",
|
||||
"type": "Python script text executable, ASCII text"
|
||||
},
|
||||
{
|
||||
"filename": "blkid-p.out",
|
||||
"type": "ASCII text"
|
||||
},
|
||||
{
|
||||
"filename": "blkid-pi.out",
|
||||
"type": "ASCII text, with very long lines"
|
||||
},
|
||||
{
|
||||
"filename": "cd_catalog.xml",
|
||||
"type": "XML 1.0 document text, ASCII text, with CRLF line terminators"
|
||||
},
|
||||
{
|
||||
"filename": "centosserial.sh",
|
||||
"type": "Bourne-Again shell script text executable, UTF-8 Unicode text"
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
import jc.parsers.universal
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'file command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'aix', 'freebsd', 'darwin']
|
||||
magic_commands = ['file']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"filename": string,
|
||||
"type ": string
|
||||
}
|
||||
]
|
||||
"""
|
||||
# No further processing
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
|
||||
warned = False
|
||||
for line in filter(None, data.splitlines()):
|
||||
linedata = line.rsplit(':', maxsplit=1)
|
||||
|
||||
try:
|
||||
filename = linedata[0].strip()
|
||||
filetype = linedata[1].strip()
|
||||
|
||||
raw_output.append(
|
||||
{
|
||||
'filename': filename,
|
||||
'type': filetype
|
||||
}
|
||||
)
|
||||
except IndexError:
|
||||
if not warned:
|
||||
jc.utils.warning_message('Filenames with newline characters detected. Some filenames may be truncated.')
|
||||
warned = True
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
@@ -77,12 +77,8 @@ def parse(data, raw=False, quiet=False):
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
for line in filter(None, data.splitlines()):
|
||||
# parse the content
|
||||
pass
|
||||
|
||||
|
||||
190
jc/parsers/group.py
Normal file
190
jc/parsers/group.py
Normal file
@@ -0,0 +1,190 @@
|
||||
"""jc - JSON CLI output utility /etc/group file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --group as the first argument if the piped input is coming from /etc/group
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/group | jc --group -p
|
||||
[
|
||||
{
|
||||
"group_name": "nobody",
|
||||
"password": "*",
|
||||
"gid": -2,
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "nogroup",
|
||||
"password": "*",
|
||||
"gid": -1,
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "wheel",
|
||||
"password": "*",
|
||||
"gid": 0,
|
||||
"members": [
|
||||
"root"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "certusers",
|
||||
"password": "*",
|
||||
"gid": 29,
|
||||
"members": [
|
||||
"root",
|
||||
"_jabber",
|
||||
"_postfix",
|
||||
"_cyrus",
|
||||
"_calendar",
|
||||
"_dovecot"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ cat /etc/group | jc --group -p -r
|
||||
[
|
||||
{
|
||||
"group_name": "nobody",
|
||||
"password": "*",
|
||||
"gid": "-2",
|
||||
"members": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "nogroup",
|
||||
"password": "*",
|
||||
"gid": "-1",
|
||||
"members": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "wheel",
|
||||
"password": "*",
|
||||
"gid": "0",
|
||||
"members": [
|
||||
"root"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "certusers",
|
||||
"password": "*",
|
||||
"gid": "29",
|
||||
"members": [
|
||||
"root",
|
||||
"_jabber",
|
||||
"_postfix",
|
||||
"_cyrus",
|
||||
"_calendar",
|
||||
"_dovecot"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = '/etc/group file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"group_name": string,
|
||||
"password": string,
|
||||
"gid": integer,
|
||||
"members": [
|
||||
string
|
||||
]
|
||||
}
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
int_list = ['gid']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
key_int = int(entry[key])
|
||||
entry[key] = key_int
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
if entry['members'] == ['']:
|
||||
entry['members'] = []
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
for entry in cleandata:
|
||||
if entry.startswith('#'):
|
||||
continue
|
||||
|
||||
output_line = {}
|
||||
fields = entry.split(':')
|
||||
|
||||
output_line['group_name'] = fields[0]
|
||||
output_line['password'] = fields[1]
|
||||
output_line['gid'] = fields[2]
|
||||
output_line['members'] = fields[3].split(',')
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
152
jc/parsers/gshadow.py
Normal file
152
jc/parsers/gshadow.py
Normal file
@@ -0,0 +1,152 @@
|
||||
"""jc - JSON CLI output utility /etc/gshadow file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --gshadow as the first argument if the piped input is coming from /etc/gshadow
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/gshadow | jc --gshadow -p
|
||||
[
|
||||
{
|
||||
"group_name": "root",
|
||||
"password": "*",
|
||||
"administrators": [],
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "adm",
|
||||
"password": "*",
|
||||
"administrators": [],
|
||||
"members": [
|
||||
"syslog",
|
||||
"joeuser"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ cat /etc/gshadow | jc --gshadow -p -r
|
||||
[
|
||||
{
|
||||
"group_name": "root",
|
||||
"password": "*",
|
||||
"administrators": [
|
||||
""
|
||||
],
|
||||
"members": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "adm",
|
||||
"password": "*",
|
||||
"administrators": [
|
||||
""
|
||||
],
|
||||
"members": [
|
||||
"syslog",
|
||||
"joeuser"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = '/etc/gshadow file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"group_name": string,
|
||||
"password": string,
|
||||
"administrators": [
|
||||
string
|
||||
],
|
||||
"members": [
|
||||
string
|
||||
]
|
||||
}
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
if entry['administrators'] == ['']:
|
||||
entry['administrators'] = []
|
||||
|
||||
if entry['members'] == ['']:
|
||||
entry['members'] = []
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
for entry in cleandata:
|
||||
if entry.startswith('#'):
|
||||
continue
|
||||
|
||||
output_line = {}
|
||||
fields = entry.split(':')
|
||||
|
||||
output_line['group_name'] = fields[0]
|
||||
output_line['password'] = fields[1]
|
||||
output_line['administrators'] = fields[2].split(',')
|
||||
output_line['members'] = fields[3].split(',')
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
@@ -40,18 +40,18 @@ Examples:
|
||||
...
|
||||
}
|
||||
"""
|
||||
import jc
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
version = '1.2'
|
||||
description = 'history command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
details = 'Optimizations by https://github.com/philippeitis'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
magic_commands = ['history']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
@@ -80,21 +80,11 @@ def process(proc_data):
|
||||
# rebuild output for added semantic information
|
||||
processed = []
|
||||
for k, v in proc_data.items():
|
||||
proc_line = {}
|
||||
proc_line['line'] = k
|
||||
proc_line['command'] = v
|
||||
proc_line = {
|
||||
'line': int(k) if k.isdigit() else None,
|
||||
'command': v,
|
||||
}
|
||||
processed.append(proc_line)
|
||||
|
||||
for entry in processed:
|
||||
int_list = ['line']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
key_int = int(entry[key])
|
||||
entry[key] = key_int
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
return processed
|
||||
|
||||
|
||||
@@ -121,17 +111,14 @@ def parse(data, raw=False, quiet=False):
|
||||
# split lines and clear out any non-ascii chars
|
||||
linedata = data.encode('ascii', errors='ignore').decode().splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, linedata))
|
||||
|
||||
if cleandata:
|
||||
for entry in cleandata:
|
||||
try:
|
||||
parsed_line = entry.split(maxsplit=1)
|
||||
raw_output[parsed_line[0]] = parsed_line[1]
|
||||
except IndexError:
|
||||
# need to catch indexerror in case there is weird input from prior commands
|
||||
pass
|
||||
# Skip any blank lines
|
||||
for entry in filter(None, linedata):
|
||||
try:
|
||||
parsed_line = entry.split(maxsplit=1)
|
||||
raw_output[parsed_line[0]] = parsed_line[1]
|
||||
except IndexError:
|
||||
# need to catch indexerror in case there is weird input from prior commands
|
||||
pass
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
|
||||
181
jc/parsers/last.py
Normal file
181
jc/parsers/last.py
Normal file
@@ -0,0 +1,181 @@
|
||||
"""jc - JSON CLI output utility last Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --last as the first argument if the piped input is coming from last or lastb
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ last | jc --last -p
|
||||
[
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys002",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 14:31",
|
||||
"logout": "still logged in"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 10:38",
|
||||
"logout": "10:38",
|
||||
"duration": "00:00"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 10:18",
|
||||
"logout": "10:18",
|
||||
"duration": "00:00"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ last | jc --last -p -r
|
||||
[
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys002",
|
||||
"hostname": "-",
|
||||
"login": "Thu Feb 27 14:31",
|
||||
"logout": "still_logged_in"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": "-",
|
||||
"login": "Thu Feb 27 10:38",
|
||||
"logout": "10:38",
|
||||
"duration": "00:00"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": "-",
|
||||
"login": "Thu Feb 27 10:18",
|
||||
"logout": "10:18",
|
||||
"duration": "00:00"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
"""
|
||||
import re
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'last and lastb command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'aix', 'freebsd']
|
||||
magic_commands = ['last', 'lastb']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"user": string,
|
||||
"tty": string,
|
||||
"hostname": string,
|
||||
"login": string,
|
||||
"logout": string,
|
||||
"duration": string
|
||||
}
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
if 'tty' in entry and entry['tty'] == '~':
|
||||
entry['tty'] = None
|
||||
|
||||
if 'tty' in entry and entry['tty'] == 'system_boot':
|
||||
entry['tty'] = 'system boot'
|
||||
|
||||
if 'hostname' in entry and entry['hostname'] == '-':
|
||||
entry['hostname'] = None
|
||||
|
||||
if 'logout' in entry and entry['logout'] == 'still_logged_in':
|
||||
entry['logout'] = 'still logged in'
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
for entry in cleandata:
|
||||
output_line = {}
|
||||
|
||||
if entry.startswith('wtmp begins ') or entry.startswith('btmp begins '):
|
||||
continue
|
||||
|
||||
entry = entry.replace('system boot', 'system_boot')
|
||||
entry = entry.replace(' still logged in', '- still_logged_in')
|
||||
|
||||
linedata = entry.split()
|
||||
if re.match(r'[MTWFS][ouerha][nedritnu] [JFMASOND][aepuco][nbrynlgptvc]', ' '.join(linedata[2:4])):
|
||||
linedata.insert(2, '-')
|
||||
|
||||
output_line['user'] = linedata[0]
|
||||
output_line['tty'] = linedata[1]
|
||||
output_line['hostname'] = linedata[2]
|
||||
output_line['login'] = ' '.join(linedata[3:7])
|
||||
|
||||
if len(linedata) > 8:
|
||||
output_line['logout'] = linedata[8]
|
||||
|
||||
if len(linedata) > 9:
|
||||
output_line['duration'] = linedata[9].replace('(', '').replace(')', '')
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
@@ -1,15 +1,20 @@
|
||||
"""jc - JSON CLI output utility ls Parser
|
||||
|
||||
Note: The -l or -b option of ls should be used to correctly parse filenames that include newline characters.
|
||||
Since ls does not encode newlines in filenames when outputting to a pipe it will cause jc to see
|
||||
multiple files instead of a single file if -l or -b is not used.
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ls as the first argument if the piped input is coming from ls
|
||||
|
||||
ls options supported:
|
||||
- None
|
||||
- la
|
||||
- h file sizes will be available in text form with -r but larger file sizes
|
||||
with human readable suffixes will be converted to Null in default view
|
||||
since the parser attempts to convert this field to an integer.
|
||||
|
||||
-lbaR
|
||||
--time-style=full-iso
|
||||
-h file sizes will be available in text form with -r but larger file sizes
|
||||
with human readable suffixes will be converted to Null in default view
|
||||
since the parser attempts to convert this field to an integer.
|
||||
|
||||
Compatibility:
|
||||
|
||||
@@ -144,7 +149,7 @@ import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
version = '1.3'
|
||||
description = 'ls command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
@@ -174,6 +179,7 @@ def process(proc_data):
|
||||
"filename": string,
|
||||
"flags": string,
|
||||
"links": integer,
|
||||
"parent": string,
|
||||
"owner": string,
|
||||
"group": string,
|
||||
"size": integer,
|
||||
@@ -213,27 +219,63 @@ def parse(data, raw=False, quiet=False):
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
warned = False
|
||||
parent = ''
|
||||
next_is_parent = False
|
||||
new_section = False
|
||||
|
||||
linedata = data.splitlines()
|
||||
|
||||
# Delete first line if it starts with 'total'
|
||||
# Delete first line if it starts with 'total 1234'
|
||||
if linedata:
|
||||
if linedata[0].find('total') == 0:
|
||||
if re.match(r'total [0-9]+', linedata[0]):
|
||||
linedata.pop(0)
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, linedata))
|
||||
# Look for parent line if glob or -R is used
|
||||
if not re.match(r'[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', linedata[0]) \
|
||||
and linedata[0].endswith(':'):
|
||||
parent = linedata.pop(0)[:-1]
|
||||
# Pop following total line
|
||||
linedata.pop(0)
|
||||
|
||||
if cleandata:
|
||||
if linedata:
|
||||
# Check if -l was used to parse extra data
|
||||
if re.match('^[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', cleandata[0]):
|
||||
for entry in cleandata:
|
||||
if re.match(r'[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', linedata[0]):
|
||||
for entry in linedata:
|
||||
output_line = {}
|
||||
|
||||
parsed_line = entry.split(maxsplit=8)
|
||||
|
||||
if not re.match(r'[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', entry) \
|
||||
and entry.endswith(':'):
|
||||
parent = entry[:-1]
|
||||
new_section = True
|
||||
|
||||
# fixup to remove trailing \n in previous entry
|
||||
raw_output[-1]['filename'] = raw_output[-1]['filename'][:-1]
|
||||
continue
|
||||
|
||||
if re.match(r'total [0-9]+', entry):
|
||||
new_section = False
|
||||
continue
|
||||
|
||||
# fix for OSX - doesn't print 'total xx' line if empty directory
|
||||
if new_section and entry == '':
|
||||
new_section = False
|
||||
continue
|
||||
|
||||
# fixup for filenames with newlines
|
||||
if not new_section \
|
||||
and not re.match(r'[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', entry):
|
||||
raw_output[-1]['filename'] = raw_output[-1]['filename'] + '\n' + entry
|
||||
continue
|
||||
|
||||
# split filenames and links
|
||||
filename_field = parsed_line[8].split(' -> ')
|
||||
if len(parsed_line) == 9:
|
||||
filename_field = parsed_line[8].split(' -> ')
|
||||
else:
|
||||
# in case of filenames starting with a newline character
|
||||
filename_field = ['']
|
||||
|
||||
# create list of dictionaries
|
||||
output_line['filename'] = filename_field[0]
|
||||
@@ -241,6 +283,9 @@ def parse(data, raw=False, quiet=False):
|
||||
if len(filename_field) > 1:
|
||||
output_line['link_to'] = filename_field[1]
|
||||
|
||||
if parent:
|
||||
output_line['parent'] = parent
|
||||
|
||||
output_line['flags'] = parsed_line[0]
|
||||
output_line['links'] = parsed_line[1]
|
||||
output_line['owner'] = parsed_line[2]
|
||||
@@ -249,9 +294,27 @@ def parse(data, raw=False, quiet=False):
|
||||
output_line['date'] = ' '.join(parsed_line[5:8])
|
||||
raw_output.append(output_line)
|
||||
else:
|
||||
for entry in cleandata:
|
||||
for entry in linedata:
|
||||
output_line = {}
|
||||
|
||||
if entry == '':
|
||||
next_is_parent = True
|
||||
continue
|
||||
|
||||
if next_is_parent and entry.endswith(':'):
|
||||
parent = entry[:-1]
|
||||
next_is_parent = False
|
||||
continue
|
||||
|
||||
if not quiet and next_is_parent and not entry.endswith(':') and not warned:
|
||||
jc.utils.warning_message('Newline characters detected. Filenames probably corrupted. Use ls -l or -b instead.')
|
||||
warned = True
|
||||
|
||||
output_line['filename'] = entry
|
||||
|
||||
if parent:
|
||||
output_line['parent'] = parent
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
|
||||
297
jc/parsers/ntpq.py
Normal file
297
jc/parsers/ntpq.py
Normal file
@@ -0,0 +1,297 @@
|
||||
"""jc - JSON CLI output utility ntpq Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ntpq as the first argument if the piped input is coming from ntpq -p
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ ntpq -p | jc --ntpq -p
|
||||
[
|
||||
{
|
||||
"remote": "44.190.6.254",
|
||||
"refid": "127.67.113.92",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": 1,
|
||||
"poll": 64,
|
||||
"reach": 1,
|
||||
"delay": 23.399,
|
||||
"offset": -2.805,
|
||||
"jitter": 2.131,
|
||||
"state": null
|
||||
},
|
||||
{
|
||||
"remote": "ntp.wdc1.us.lea",
|
||||
"refid": "130.133.1.10",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": null,
|
||||
"poll": 64,
|
||||
"reach": 1,
|
||||
"delay": 93.053,
|
||||
"offset": -0.807,
|
||||
"jitter": 2.839,
|
||||
"state": null
|
||||
},
|
||||
{
|
||||
"remote": "clock.team-cymr",
|
||||
"refid": "204.9.54.119",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": null,
|
||||
"poll": 64,
|
||||
"reach": 1,
|
||||
"delay": 70.337,
|
||||
"offset": -2.909,
|
||||
"jitter": 2.6,
|
||||
"state": null
|
||||
},
|
||||
{
|
||||
"remote": "mirror1.sjc02.s",
|
||||
"refid": "216.218.254.202",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": 2,
|
||||
"poll": 64,
|
||||
"reach": 1,
|
||||
"delay": 29.325,
|
||||
"offset": 1.044,
|
||||
"jitter": 4.069,
|
||||
"state": null,
|
||||
}
|
||||
]
|
||||
|
||||
$ ntpq -pn| jc --ntpq -p
|
||||
[
|
||||
{
|
||||
"remote": "44.190.6.254",
|
||||
"refid": "127.67.113.92",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": 66,
|
||||
"poll": 64,
|
||||
"reach": 377,
|
||||
"delay": 22.69,
|
||||
"offset": -0.392,
|
||||
"jitter": 2.085,
|
||||
"state": "+"
|
||||
},
|
||||
{
|
||||
"remote": "108.59.2.24",
|
||||
"refid": "130.133.1.10",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": 63,
|
||||
"poll": 64,
|
||||
"reach": 377,
|
||||
"delay": 90.805,
|
||||
"offset": 2.84,
|
||||
"jitter": 1.908,
|
||||
"state": "-"
|
||||
},
|
||||
{
|
||||
"remote": "38.229.71.1",
|
||||
"refid": "204.9.54.119",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": 64,
|
||||
"poll": 64,
|
||||
"reach": 377,
|
||||
"delay": 68.699,
|
||||
"offset": -0.61,
|
||||
"jitter": 2.576,
|
||||
"state": "+"
|
||||
},
|
||||
{
|
||||
"remote": "72.5.72.15",
|
||||
"refid": "216.218.254.202",
|
||||
"st": 2,
|
||||
"t": "u",
|
||||
"when": 63,
|
||||
"poll": 64,
|
||||
"reach": 377,
|
||||
"delay": 22.654,
|
||||
"offset": 0.231,
|
||||
"jitter": 1.964,
|
||||
"state": "*"
|
||||
}
|
||||
]
|
||||
|
||||
$ ntpq -pn| jc --ntpq -p -r
|
||||
[
|
||||
{
|
||||
"s": "+",
|
||||
"remote": "44.190.6.254",
|
||||
"refid": "127.67.113.92",
|
||||
"st": "2",
|
||||
"t": "u",
|
||||
"when": "66",
|
||||
"poll": "64",
|
||||
"reach": "377",
|
||||
"delay": "22.690",
|
||||
"offset": "-0.392",
|
||||
"jitter": "2.085"
|
||||
},
|
||||
{
|
||||
"s": "-",
|
||||
"remote": "108.59.2.24",
|
||||
"refid": "130.133.1.10",
|
||||
"st": "2",
|
||||
"t": "u",
|
||||
"when": "63",
|
||||
"poll": "64",
|
||||
"reach": "377",
|
||||
"delay": "90.805",
|
||||
"offset": "2.840",
|
||||
"jitter": "1.908"
|
||||
},
|
||||
{
|
||||
"s": "+",
|
||||
"remote": "38.229.71.1",
|
||||
"refid": "204.9.54.119",
|
||||
"st": "2",
|
||||
"t": "u",
|
||||
"when": "64",
|
||||
"poll": "64",
|
||||
"reach": "377",
|
||||
"delay": "68.699",
|
||||
"offset": "-0.610",
|
||||
"jitter": "2.576"
|
||||
},
|
||||
{
|
||||
"s": "*",
|
||||
"remote": "72.5.72.15",
|
||||
"refid": "216.218.254.202",
|
||||
"st": "2",
|
||||
"t": "u",
|
||||
"when": "63",
|
||||
"poll": "64",
|
||||
"reach": "377",
|
||||
"delay": "22.654",
|
||||
"offset": "0.231",
|
||||
"jitter": "1.964"
|
||||
}
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
import jc.parsers.universal
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'ntpq -p command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['ntpq']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"state": string, # space/~ converted to null
|
||||
"remote": string,
|
||||
"refid": string,
|
||||
"st": integer,
|
||||
"t": string,
|
||||
"when": integer, # - converted to null
|
||||
"poll": integer,
|
||||
"reach": integer,
|
||||
"delay": float,
|
||||
"offset": float,
|
||||
"jitter": float
|
||||
},
|
||||
]
|
||||
|
||||
"""
|
||||
for entry in proc_data:
|
||||
|
||||
if entry['s'] == '~':
|
||||
entry['s'] = None
|
||||
|
||||
entry['state'] = entry.pop('s')
|
||||
|
||||
int_list = ['st', 'when', 'poll', 'reach']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
entry[key] = int(entry[key])
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
float_list = ['delay', 'offset', 'jitter']
|
||||
for key in float_list:
|
||||
if key in entry:
|
||||
try:
|
||||
entry[key] = float(entry[key])
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
|
||||
cleandata = data.splitlines()
|
||||
cleandata[0] = 's ' + cleandata[0]
|
||||
cleandata[0] = cleandata[0].lower()
|
||||
|
||||
# delete header delimiter
|
||||
del cleandata[1]
|
||||
|
||||
# separate first character with a space for easier parsing
|
||||
for i, line in list(enumerate(cleandata[1:])):
|
||||
if line[0] == ' ':
|
||||
# fixup for no-state
|
||||
cleandata[i + 1] = '~ ' + line[1:]
|
||||
else:
|
||||
# fixup - realign columns since we added the 's' column
|
||||
cleandata[i + 1] = line[:1] + ' ' + line[1:]
|
||||
|
||||
# fixup for occaisional ip/hostname fields with a space
|
||||
cleandata[i + 1] = cleandata[i + 1].replace(' (', '_(')
|
||||
|
||||
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
175
jc/parsers/passwd.py
Normal file
175
jc/parsers/passwd.py
Normal file
@@ -0,0 +1,175 @@
|
||||
"""jc - JSON CLI output utility /etc/passwd file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --passwd as the first argument if the piped input is coming from /etc/passwd
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/passwd | jc --passwd -p
|
||||
[
|
||||
{
|
||||
"username": "nobody",
|
||||
"password": "*",
|
||||
"uid": -2,
|
||||
"gid": -2,
|
||||
"comment": "Unprivileged User",
|
||||
"home": "/var/empty",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"comment": "System Administrator",
|
||||
"home": "/var/root",
|
||||
"shell": "/bin/sh"
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"uid": 1,
|
||||
"gid": 1,
|
||||
"comment": "System Services",
|
||||
"home": "/var/root",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ cat /etc/passwd | jc --passwd -p -r
|
||||
[
|
||||
{
|
||||
"username": "nobody",
|
||||
"password": "*",
|
||||
"uid": "-2",
|
||||
"gid": "-2",
|
||||
"comment": "Unprivileged User",
|
||||
"home": "/var/empty",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"uid": "0",
|
||||
"gid": "0",
|
||||
"comment": "System Administrator",
|
||||
"home": "/var/root",
|
||||
"shell": "/bin/sh"
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"uid": "1",
|
||||
"gid": "1",
|
||||
"comment": "System Services",
|
||||
"home": "/var/root",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = '/etc/passwd file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"username": string,
|
||||
"password": string,
|
||||
"uid": integer,
|
||||
"gid": integer,
|
||||
"comment": string,
|
||||
"home": string,
|
||||
"shell": string
|
||||
}
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
int_list = ['uid', 'gid']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
key_int = int(entry[key])
|
||||
entry[key] = key_int
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
for entry in cleandata:
|
||||
if entry.startswith('#'):
|
||||
continue
|
||||
|
||||
output_line = {}
|
||||
fields = entry.split(':')
|
||||
|
||||
output_line['username'] = fields[0]
|
||||
output_line['password'] = fields[1]
|
||||
output_line['uid'] = fields[2]
|
||||
output_line['gid'] = fields[3]
|
||||
output_line['comment'] = fields[4]
|
||||
output_line['home'] = fields[5]
|
||||
output_line['shell'] = fields[6]
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
183
jc/parsers/shadow.py
Normal file
183
jc/parsers/shadow.py
Normal file
@@ -0,0 +1,183 @@
|
||||
"""jc - JSON CLI output utility /etc/shadow file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --shadow as the first argument if the piped input is coming from /etc/shadow
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ sudo cat /etc/shadow | jc --shadow -p
|
||||
[
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
{
|
||||
"username": "bin",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ sudo cat /etc/shadow | jc --shadow -p -r
|
||||
[
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"last_changed": "18113",
|
||||
"minimum": "0",
|
||||
"maximum": "99999",
|
||||
"warn": "7",
|
||||
"inactive": "",
|
||||
"expire": ""
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"last_changed": "18113",
|
||||
"minimum": "0",
|
||||
"maximum": "99999",
|
||||
"warn": "7",
|
||||
"inactive": "",
|
||||
"expire": ""
|
||||
},
|
||||
{
|
||||
"username": "bin",
|
||||
"password": "*",
|
||||
"last_changed": "18113",
|
||||
"minimum": "0",
|
||||
"maximum": "99999",
|
||||
"warn": "7",
|
||||
"inactive": "",
|
||||
"expire": ""
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = '/etc/shadow file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"username": string,
|
||||
"password": string,
|
||||
"last_changed": integer,
|
||||
"minimum": integer,
|
||||
"maximum": integer,
|
||||
"warn": integer,
|
||||
"inactive": integer,
|
||||
"expire": integer
|
||||
}
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
int_list = ['last_changed', 'minimum', 'maximum', 'warn', 'inactive', 'expire']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
key_int = int(entry[key])
|
||||
entry[key] = key_int
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
for entry in cleandata:
|
||||
if entry.startswith('#'):
|
||||
continue
|
||||
|
||||
output_line = {}
|
||||
fields = entry.split(':')
|
||||
|
||||
output_line['username'] = fields[0]
|
||||
output_line['password'] = fields[1]
|
||||
output_line['last_changed'] = fields[2]
|
||||
output_line['minimum'] = fields[3]
|
||||
output_line['maximum'] = fields[4]
|
||||
output_line['warn'] = fields[5]
|
||||
output_line['inactive'] = fields[6]
|
||||
output_line['expire'] = fields[7]
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
122
jc/parsers/timedatectl.py
Normal file
122
jc/parsers/timedatectl.py
Normal file
@@ -0,0 +1,122 @@
|
||||
"""jc - JSON CLI output utility timedatectl Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --timedatectl as the first argument if the piped input is coming from timedatectl or timedatectl status
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ timedatectl | jc --timedatectl -p
|
||||
{
|
||||
"local_time": "Tue 2020-03-10 17:53:21 PDT",
|
||||
"universal_time": "Wed 2020-03-11 00:53:21 UTC",
|
||||
"rtc_time": "Wed 2020-03-11 00:53:21",
|
||||
"time_zone": "America/Los_Angeles (PDT, -0700)",
|
||||
"ntp_enabled": true,
|
||||
"ntp_synchronized": true,
|
||||
"rtc_in_local_tz": false,
|
||||
"dst_active": true
|
||||
}
|
||||
|
||||
$ timedatectl | jc --timedatectl -p -r
|
||||
{
|
||||
"local_time": "Tue 2020-03-10 17:53:21 PDT",
|
||||
"universal_time": "Wed 2020-03-11 00:53:21 UTC",
|
||||
"rtc_time": "Wed 2020-03-11 00:53:21",
|
||||
"time_zone": "America/Los_Angeles (PDT, -0700)",
|
||||
"ntp_enabled": "yes",
|
||||
"ntp_synchronized": "yes",
|
||||
"rtc_in_local_tz": "no",
|
||||
"dst_active": "yes"
|
||||
}
|
||||
"""
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'timedatectl status command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['timedatectl', 'timedatectl status']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Structured data with the following schema:
|
||||
|
||||
{
|
||||
"local_time": string,
|
||||
"universal_time": string,
|
||||
"rtc_time": string,
|
||||
"time_zone": string,
|
||||
"ntp_enabled": boolean,
|
||||
"ntp_synchronized": boolean,
|
||||
"system_clock_synchronized": boolean,
|
||||
"systemd-timesyncd.service_active": boolean,
|
||||
"rtc_in_local_tz": boolean,
|
||||
"dst_active": boolean
|
||||
}
|
||||
"""
|
||||
# boolean changes
|
||||
bool_list = ['ntp_enabled', 'ntp_synchronized', 'rtc_in_local_tz', 'dst_active',
|
||||
'system_clock_synchronized', 'systemd-timesyncd.service_active']
|
||||
for key in proc_data:
|
||||
if key in bool_list:
|
||||
try:
|
||||
proc_data[key] = True if proc_data[key] == 'yes' else False
|
||||
except (ValueError):
|
||||
proc_data[key] = None
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
Dictionary. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = {}
|
||||
|
||||
for line in filter(None, data.splitlines()):
|
||||
linedata = line.split(':', maxsplit=1)
|
||||
raw_output[linedata[0].strip().lower().replace(' ', '_')] = linedata[1].strip()
|
||||
|
||||
if linedata[0].strip() == 'DST active':
|
||||
break
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
284
jc/parsers/who.py
Normal file
284
jc/parsers/who.py
Normal file
@@ -0,0 +1,284 @@
|
||||
"""jc - JSON CLI output utility who Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --who as the first argument if the piped input is coming from who
|
||||
|
||||
accepts any of the following who options (or no options): -aTH
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ who -a | jc --who -p
|
||||
[
|
||||
{
|
||||
"event": "reboot",
|
||||
"time": "Feb 7 23:31",
|
||||
"pid": 1
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "-",
|
||||
"tty": "console",
|
||||
"time": "Feb 7 23:32",
|
||||
"idle": "old",
|
||||
"pid": 105
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys000",
|
||||
"time": "Feb 13 16:44",
|
||||
"idle": ".",
|
||||
"pid": 51217,
|
||||
"comment": "term=0 exit=0"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "?",
|
||||
"tty": "ttys003",
|
||||
"time": "Feb 28 08:59",
|
||||
"idle": "01:36",
|
||||
"pid": 41402
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys004",
|
||||
"time": "Mar 1 16:35",
|
||||
"idle": ".",
|
||||
"pid": 15679,
|
||||
"from": "192.168.1.5"
|
||||
}
|
||||
]
|
||||
|
||||
$ who -a | jc --who -p -r
|
||||
[
|
||||
{
|
||||
"event": "reboot",
|
||||
"time": "Feb 7 23:31",
|
||||
"pid": "1"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "-",
|
||||
"tty": "console",
|
||||
"time": "Feb 7 23:32",
|
||||
"idle": "old",
|
||||
"pid": "105"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys000",
|
||||
"time": "Feb 13 16:44",
|
||||
"idle": ".",
|
||||
"pid": "51217",
|
||||
"comment": "term=0 exit=0"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "?",
|
||||
"tty": "ttys003",
|
||||
"time": "Feb 28 08:59",
|
||||
"idle": "01:36",
|
||||
"pid": "41402"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys004",
|
||||
"time": "Mar 1 16:35",
|
||||
"idle": ".",
|
||||
"pid": "15679",
|
||||
"from": "192.168.1.5"
|
||||
}
|
||||
]
|
||||
"""
|
||||
import re
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'who command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
magic_commands = ['who']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"user": string,
|
||||
"event": string,
|
||||
"writeable_tty": string,
|
||||
"tty": string,
|
||||
"time": string,
|
||||
"idle": string,
|
||||
"pid": integer,
|
||||
"from": string,
|
||||
"comment": string
|
||||
}
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
int_list = ['pid']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
key_int = int(entry[key])
|
||||
entry[key] = key_int
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
for line in cleandata:
|
||||
output_line = {}
|
||||
linedata = line.split()
|
||||
|
||||
# clear headers, if they exist
|
||||
if ''.join(linedata[0:3]) == 'NAMELINETIME' \
|
||||
or ''.join(linedata[0:3]) == 'USERLINEWHEN':
|
||||
linedata.pop(0)
|
||||
continue
|
||||
|
||||
# mac reboot line
|
||||
if linedata[0] == 'reboot':
|
||||
output_line['event'] = 'reboot'
|
||||
output_line['time'] = ' '.join(linedata[2:5])
|
||||
output_line['pid'] = linedata[6]
|
||||
raw_output.append(output_line)
|
||||
continue
|
||||
|
||||
# linux reboot line
|
||||
if ''.join(linedata[0:2]) == 'systemboot':
|
||||
output_line['event'] = 'reboot'
|
||||
output_line['time'] = ' '.join(linedata[2:4])
|
||||
raw_output.append(output_line)
|
||||
continue
|
||||
|
||||
# linux login line
|
||||
if linedata[0] == 'LOGIN':
|
||||
output_line['event'] = 'login'
|
||||
output_line['tty'] = linedata[1]
|
||||
output_line['time'] = ' '.join(linedata[2:4])
|
||||
output_line['pid'] = linedata[4]
|
||||
if len(linedata) > 5:
|
||||
output_line['comment'] = ' '.join(linedata[5:])
|
||||
raw_output.append(output_line)
|
||||
continue
|
||||
|
||||
# linux run-level
|
||||
if linedata[0] == 'run-level':
|
||||
output_line['event'] = ' '.join(linedata[0:2])
|
||||
output_line['time'] = ' '.join(linedata[2:4])
|
||||
raw_output.append(output_line)
|
||||
continue
|
||||
|
||||
# mac run-level (ignore because not enough useful info)
|
||||
if linedata[1] == 'run-level':
|
||||
continue
|
||||
|
||||
# pts lines with no user information
|
||||
if linedata[0].startswith('pts/'):
|
||||
output_line['tty'] = linedata[0]
|
||||
output_line['time'] = ' '.join(linedata[1:3])
|
||||
output_line['pid'] = linedata[3]
|
||||
output_line['comment'] = ' '.join(linedata[4:])
|
||||
raw_output.append(output_line)
|
||||
continue
|
||||
|
||||
# user logins
|
||||
output_line['user'] = linedata.pop(0)
|
||||
|
||||
if linedata[0] in '+-?':
|
||||
output_line['writeable_tty'] = linedata.pop(0)
|
||||
|
||||
output_line['tty'] = linedata.pop(0)
|
||||
|
||||
# mac
|
||||
if re.match(r'[JFMASOND][aepuco][nbrynlgptvc]', linedata[0]):
|
||||
output_line['time'] = ' '.join([linedata.pop(0),
|
||||
linedata.pop(0),
|
||||
linedata.pop(0)])
|
||||
# linux
|
||||
else:
|
||||
output_line['time'] = ' '.join([linedata.pop(0),
|
||||
linedata.pop(0)])
|
||||
|
||||
# if just one more field, then it's the remote IP
|
||||
if len(linedata) == 1:
|
||||
output_line['from'] = linedata[0].replace('(', '').replace(')', '')
|
||||
raw_output.append(output_line)
|
||||
continue
|
||||
|
||||
# extended info: idle
|
||||
if len(linedata) > 0:
|
||||
output_line['idle'] = linedata.pop(0)
|
||||
|
||||
# extended info: pid
|
||||
if len(linedata) > 0:
|
||||
output_line['pid'] = linedata.pop(0)
|
||||
|
||||
# extended info is from
|
||||
if len(linedata) > 0 and linedata[0].startswith('('):
|
||||
output_line['from'] = linedata[0].replace('(', '').replace(')', '')
|
||||
|
||||
# else, extended info is comment
|
||||
elif len(linedata) > 0:
|
||||
output_line['comment'] = ' '.join(linedata)
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
ifconfig-parser>=0.0.5
|
||||
ruamel.yaml>=0.15.0
|
||||
xmltodict>=0.12.0
|
||||
2
setup.py
2
setup.py
@@ -5,7 +5,7 @@ with open('README.md', 'r') as f:
|
||||
|
||||
setuptools.setup(
|
||||
name='jc',
|
||||
version='1.7.3',
|
||||
version='1.9.0',
|
||||
author='Kelly Brazil',
|
||||
author_email='kellyjonbrazil@gmail.com',
|
||||
description='This tool serializes the output of popular command line tools and filetypes to structured JSON output.',
|
||||
|
||||
1
tests/fixtures/centos-7.7/blkid-ip-multi.json
vendored
Normal file
1
tests/fixtures/centos-7.7/blkid-ip-multi.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"uuid": "3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM", "version": "LVM2 001", "type": "LVM2_member", "usage": "raid", "minimum_io_size": 512, "physical_sector_size": 512, "logical_sector_size": 512, "part_entry_scheme": "dos", "part_entry_type": "0x8e", "part_entry_number": 2, "part_entry_offset": 2099200, "part_entry_size": 39843840, "part_entry_disk": "8:0", "device": "/dev/sda2"}, {"uuid": "05d927bb-5875-49e3-ada1-7f46cb31c932", "type": "xfs", "usage": "filesystem", "minimum_io_size": 512, "physical_sector_size": 512, "logical_sector_size": 512, "part_entry_scheme": "dos", "part_entry_type": "0x83", "part_entry_flags": "0x80", "part_entry_number": 1, "part_entry_offset": 2048, "part_entry_size": 2097152, "part_entry_disk": "8:0", "device": "/dev/sda1"}]
|
||||
29
tests/fixtures/centos-7.7/blkid-ip-multi.out
vendored
Normal file
29
tests/fixtures/centos-7.7/blkid-ip-multi.out
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
DEVNAME=/dev/sda2
|
||||
UUID=3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM
|
||||
VERSION=LVM2 001
|
||||
TYPE=LVM2_member
|
||||
USAGE=raid
|
||||
MINIMUM_IO_SIZE=512
|
||||
PHYSICAL_SECTOR_SIZE=512
|
||||
LOGICAL_SECTOR_SIZE=512
|
||||
PART_ENTRY_SCHEME=dos
|
||||
PART_ENTRY_TYPE=0x8e
|
||||
PART_ENTRY_NUMBER=2
|
||||
PART_ENTRY_OFFSET=2099200
|
||||
PART_ENTRY_SIZE=39843840
|
||||
PART_ENTRY_DISK=8:0
|
||||
|
||||
DEVNAME=/dev/sda1
|
||||
UUID=05d927bb-5875-49e3-ada1-7f46cb31c932
|
||||
TYPE=xfs
|
||||
USAGE=filesystem
|
||||
MINIMUM_IO_SIZE=512
|
||||
PHYSICAL_SECTOR_SIZE=512
|
||||
LOGICAL_SECTOR_SIZE=512
|
||||
PART_ENTRY_SCHEME=dos
|
||||
PART_ENTRY_TYPE=0x83
|
||||
PART_ENTRY_FLAGS=0x80
|
||||
PART_ENTRY_NUMBER=1
|
||||
PART_ENTRY_OFFSET=2048
|
||||
PART_ENTRY_SIZE=2097152
|
||||
PART_ENTRY_DISK=8:0
|
||||
1
tests/fixtures/centos-7.7/blkid-ip-udev-multi.json
vendored
Normal file
1
tests/fixtures/centos-7.7/blkid-ip-udev-multi.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"id_fs_uuid": "3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM", "id_fs_uuid_enc": "3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM", "id_fs_version": "LVM2\\x20001", "id_fs_type": "LVM2_member", "id_fs_usage": "raid", "id_iolimit_minimum_io_size": 512, "id_iolimit_physical_sector_size": 512, "id_iolimit_logical_sector_size": 512, "id_part_entry_scheme": "dos", "id_part_entry_type": "0x8e", "id_part_entry_number": 2, "id_part_entry_offset": 2099200, "id_part_entry_size": 39843840, "id_part_entry_disk": "8:0"}, {"id_fs_uuid": "05d927bb-5875-49e3-ada1-7f46cb31c932", "id_fs_uuid_enc": "05d927bb-5875-49e3-ada1-7f46cb31c932", "id_fs_type": "xfs", "id_fs_usage": "filesystem", "id_iolimit_minimum_io_size": 512, "id_iolimit_physical_sector_size": 512, "id_iolimit_logical_sector_size": 512, "id_part_entry_scheme": "dos", "id_part_entry_type": "0x83", "id_part_entry_flags": "0x80", "id_part_entry_number": 1, "id_part_entry_offset": 2048, "id_part_entry_size": 2097152, "id_part_entry_disk": "8:0"}]
|
||||
29
tests/fixtures/centos-7.7/blkid-ip-udev-multi.out
vendored
Normal file
29
tests/fixtures/centos-7.7/blkid-ip-udev-multi.out
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
ID_FS_UUID=3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM
|
||||
ID_FS_UUID_ENC=3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM
|
||||
ID_FS_VERSION=LVM2\x20001
|
||||
ID_FS_TYPE=LVM2_member
|
||||
ID_FS_USAGE=raid
|
||||
ID_IOLIMIT_MINIMUM_IO_SIZE=512
|
||||
ID_IOLIMIT_PHYSICAL_SECTOR_SIZE=512
|
||||
ID_IOLIMIT_LOGICAL_SECTOR_SIZE=512
|
||||
ID_PART_ENTRY_SCHEME=dos
|
||||
ID_PART_ENTRY_TYPE=0x8e
|
||||
ID_PART_ENTRY_NUMBER=2
|
||||
ID_PART_ENTRY_OFFSET=2099200
|
||||
ID_PART_ENTRY_SIZE=39843840
|
||||
ID_PART_ENTRY_DISK=8:0
|
||||
|
||||
ID_FS_UUID=05d927bb-5875-49e3-ada1-7f46cb31c932
|
||||
ID_FS_UUID_ENC=05d927bb-5875-49e3-ada1-7f46cb31c932
|
||||
ID_FS_TYPE=xfs
|
||||
ID_FS_USAGE=filesystem
|
||||
ID_IOLIMIT_MINIMUM_IO_SIZE=512
|
||||
ID_IOLIMIT_PHYSICAL_SECTOR_SIZE=512
|
||||
ID_IOLIMIT_LOGICAL_SECTOR_SIZE=512
|
||||
ID_PART_ENTRY_SCHEME=dos
|
||||
ID_PART_ENTRY_TYPE=0x83
|
||||
ID_PART_ENTRY_FLAGS=0x80
|
||||
ID_PART_ENTRY_NUMBER=1
|
||||
ID_PART_ENTRY_OFFSET=2048
|
||||
ID_PART_ENTRY_SIZE=2097152
|
||||
ID_PART_ENTRY_DISK=8:0
|
||||
1
tests/fixtures/centos-7.7/blkid-ip-udev.json
vendored
Normal file
1
tests/fixtures/centos-7.7/blkid-ip-udev.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"id_fs_uuid": "05d927bb-5875-49e3-ada1-7f46cb31c932", "id_fs_uuid_enc": "05d927bb-5875-49e3-ada1-7f46cb31c932", "id_fs_type": "xfs", "id_fs_usage": "filesystem", "id_iolimit_minimum_io_size": 512, "id_iolimit_physical_sector_size": 512, "id_iolimit_logical_sector_size": 512, "id_part_entry_scheme": "dos", "id_part_entry_type": "0x83", "id_part_entry_flags": "0x80", "id_part_entry_number": 1, "id_part_entry_offset": 2048, "id_part_entry_size": 2097152, "id_part_entry_disk": "8:0"}]
|
||||
14
tests/fixtures/centos-7.7/blkid-ip-udev.out
vendored
Normal file
14
tests/fixtures/centos-7.7/blkid-ip-udev.out
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
ID_FS_UUID=05d927bb-5875-49e3-ada1-7f46cb31c932
|
||||
ID_FS_UUID_ENC=05d927bb-5875-49e3-ada1-7f46cb31c932
|
||||
ID_FS_TYPE=xfs
|
||||
ID_FS_USAGE=filesystem
|
||||
ID_IOLIMIT_MINIMUM_IO_SIZE=512
|
||||
ID_IOLIMIT_PHYSICAL_SECTOR_SIZE=512
|
||||
ID_IOLIMIT_LOGICAL_SECTOR_SIZE=512
|
||||
ID_PART_ENTRY_SCHEME=dos
|
||||
ID_PART_ENTRY_TYPE=0x83
|
||||
ID_PART_ENTRY_FLAGS=0x80
|
||||
ID_PART_ENTRY_NUMBER=1
|
||||
ID_PART_ENTRY_OFFSET=2048
|
||||
ID_PART_ENTRY_SIZE=2097152
|
||||
ID_PART_ENTRY_DISK=8:0
|
||||
1
tests/fixtures/centos-7.7/blkid-sda2.json
vendored
Normal file
1
tests/fixtures/centos-7.7/blkid-sda2.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"device": "/dev/sda2", "uuid": "3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM", "type": "LVM2_member"}]
|
||||
1
tests/fixtures/centos-7.7/blkid-sda2.out
vendored
Normal file
1
tests/fixtures/centos-7.7/blkid-sda2.out
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/dev/sda2: UUID="3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM" TYPE="LVM2_member"
|
||||
1
tests/fixtures/centos-7.7/blkid.json
vendored
Normal file
1
tests/fixtures/centos-7.7/blkid.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"device": "/dev/sda1", "uuid": "05d927bb-5875-49e3-ada1-7f46cb31c932", "type": "xfs"}, {"device": "/dev/sda2", "uuid": "3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM", "type": "LVM2_member"}, {"device": "/dev/mapper/centos-root", "uuid": "07d718ef-950c-4e5b-98e0-42a1147b77d9", "type": "xfs"}, {"device": "/dev/mapper/centos-swap", "uuid": "615eb89d-bcbf-46ad-80e3-c483ef5c931f", "type": "swap"}]
|
||||
4
tests/fixtures/centos-7.7/blkid.out
vendored
Normal file
4
tests/fixtures/centos-7.7/blkid.out
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/dev/sda1: UUID="05d927bb-5875-49e3-ada1-7f46cb31c932" TYPE="xfs"
|
||||
/dev/sda2: UUID="3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM" TYPE="LVM2_member"
|
||||
/dev/mapper/centos-root: UUID="07d718ef-950c-4e5b-98e0-42a1147b77d9" TYPE="xfs"
|
||||
/dev/mapper/centos-swap: UUID="615eb89d-bcbf-46ad-80e3-c483ef5c931f" TYPE="swap"
|
||||
1
tests/fixtures/centos-7.7/file.json
vendored
Normal file
1
tests/fixtures/centos-7.7/file.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"filename": "bin", "type": "directory"}, {"filename": "digout", "type": "ASCII text"}, {"filename": "file with spaces in the name", "type": "empty"}, {"filename": "git", "type": "directory"}, {"filename": "id-centos.out", "type": "ASCII text"}, {"filename": "ifcfg.json", "type": "ASCII text, with very long lines"}, {"filename": "ifconfig.out", "type": "ASCII text"}, {"filename": "iptables-tests", "type": "directory"}, {"filename": "journaljson", "type": "ASCII text, with very long lines"}, {"filename": "jp", "type": "ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped"}, {"filename": "jp_1.1.12_linux_x86_64.zip", "type": "Zip archive data, at least v2.0 to extract"}, {"filename": "lastb.out", "type": "ASCII text"}, {"filename": "lsblk-cols", "type": "UTF-8 Unicode text"}, {"filename": "psfile.txt", "type": "ASCII text, with very long lines"}, {"filename": "resizeterm.sh", "type": "Bourne-Again shell script, ASCII text executable"}, {"filename": "routeout", "type": "ASCII text"}, {"filename": "ss-aeep.out", "type": "ASCII text"}, {"filename": "ssout", "type": "ASCII text"}, {"filename": "systemctl.out", "type": "UTF-8 Unicode text"}, {"filename": "testfiles", "type": "directory"}, {"filename": "tmp", "type": "directory"}, {"filename": "top.out", "type": "ASCII text, with escape sequences"}, {"filename": "who-aH.out", "type": "ASCII text"}, {"filename": "who.out", "type": "ASCII text"}, {"filename": "whotext", "type": "ASCII text"}]
|
||||
25
tests/fixtures/centos-7.7/file.out
vendored
Normal file
25
tests/fixtures/centos-7.7/file.out
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
bin: directory
|
||||
digout: ASCII text
|
||||
file with spaces in the name: empty
|
||||
git: directory
|
||||
id-centos.out: ASCII text
|
||||
ifcfg.json: ASCII text, with very long lines
|
||||
ifconfig.out: ASCII text
|
||||
iptables-tests: directory
|
||||
journaljson: ASCII text, with very long lines
|
||||
jp: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
|
||||
jp_1.1.12_linux_x86_64.zip: Zip archive data, at least v2.0 to extract
|
||||
lastb.out: ASCII text
|
||||
lsblk-cols: UTF-8 Unicode text
|
||||
psfile.txt: ASCII text, with very long lines
|
||||
resizeterm.sh: Bourne-Again shell script, ASCII text executable
|
||||
routeout: ASCII text
|
||||
ss-aeep.out: ASCII text
|
||||
ssout: ASCII text
|
||||
systemctl.out: UTF-8 Unicode text
|
||||
testfiles: directory
|
||||
tmp: directory
|
||||
top.out: ASCII text, with escape sequences
|
||||
who-aH.out: ASCII text
|
||||
who.out: ASCII text
|
||||
whotext: ASCII text
|
||||
1
tests/fixtures/centos-7.7/group.json
vendored
Normal file
1
tests/fixtures/centos-7.7/group.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"group_name": "root", "password": "x", "gid": 0, "members": []}, {"group_name": "bin", "password": "x", "gid": 1, "members": []}, {"group_name": "daemon", "password": "x", "gid": 2, "members": []}, {"group_name": "sys", "password": "x", "gid": 3, "members": []}, {"group_name": "adm", "password": "x", "gid": 4, "members": []}, {"group_name": "tty", "password": "x", "gid": 5, "members": []}, {"group_name": "disk", "password": "x", "gid": 6, "members": []}, {"group_name": "lp", "password": "x", "gid": 7, "members": []}, {"group_name": "mem", "password": "x", "gid": 8, "members": []}, {"group_name": "kmem", "password": "x", "gid": 9, "members": []}, {"group_name": "wheel", "password": "x", "gid": 10, "members": ["joeuser"]}, {"group_name": "cdrom", "password": "x", "gid": 11, "members": []}, {"group_name": "mail", "password": "x", "gid": 12, "members": ["postfix"]}, {"group_name": "man", "password": "x", "gid": 15, "members": []}, {"group_name": "dialout", "password": "x", "gid": 18, "members": []}, {"group_name": "floppy", "password": "x", "gid": 19, "members": []}, {"group_name": "games", "password": "x", "gid": 20, "members": []}, {"group_name": "tape", "password": "x", "gid": 33, "members": []}, {"group_name": "video", "password": "x", "gid": 39, "members": []}, {"group_name": "ftp", "password": "x", "gid": 50, "members": []}, {"group_name": "lock", "password": "x", "gid": 54, "members": []}, {"group_name": "audio", "password": "x", "gid": 63, "members": []}, {"group_name": "nobody", "password": "x", "gid": 99, "members": []}, {"group_name": "users", "password": "x", "gid": 100, "members": []}, {"group_name": "utmp", "password": "x", "gid": 22, "members": []}, {"group_name": "utempter", "password": "x", "gid": 35, "members": []}, {"group_name": "input", "password": "x", "gid": 999, "members": []}, {"group_name": "systemd-journal", "password": "x", "gid": 190, "members": []}, {"group_name": "systemd-network", "password": "x", "gid": 192, "members": []}, {"group_name": "dbus", "password": "x", "gid": 81, "members": []}, {"group_name": "polkitd", "password": "x", "gid": 998, "members": []}, {"group_name": "ssh_keys", "password": "x", "gid": 997, "members": []}, {"group_name": "sshd", "password": "x", "gid": 74, "members": []}, {"group_name": "postdrop", "password": "x", "gid": 90, "members": []}, {"group_name": "postfix", "password": "x", "gid": 89, "members": []}, {"group_name": "chrony", "password": "x", "gid": 996, "members": []}, {"group_name": "joeuser", "password": "x", "gid": 1000, "members": ["joeuser"]}, {"group_name": "cgred", "password": "x", "gid": 995, "members": []}, {"group_name": "dockerroot", "password": "x", "gid": 994, "members": []}]
|
||||
39
tests/fixtures/centos-7.7/group.out
vendored
Normal file
39
tests/fixtures/centos-7.7/group.out
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
root:x:0:
|
||||
bin:x:1:
|
||||
daemon:x:2:
|
||||
sys:x:3:
|
||||
adm:x:4:
|
||||
tty:x:5:
|
||||
disk:x:6:
|
||||
lp:x:7:
|
||||
mem:x:8:
|
||||
kmem:x:9:
|
||||
wheel:x:10:joeuser
|
||||
cdrom:x:11:
|
||||
mail:x:12:postfix
|
||||
man:x:15:
|
||||
dialout:x:18:
|
||||
floppy:x:19:
|
||||
games:x:20:
|
||||
tape:x:33:
|
||||
video:x:39:
|
||||
ftp:x:50:
|
||||
lock:x:54:
|
||||
audio:x:63:
|
||||
nobody:x:99:
|
||||
users:x:100:
|
||||
utmp:x:22:
|
||||
utempter:x:35:
|
||||
input:x:999:
|
||||
systemd-journal:x:190:
|
||||
systemd-network:x:192:
|
||||
dbus:x:81:
|
||||
polkitd:x:998:
|
||||
ssh_keys:x:997:
|
||||
sshd:x:74:
|
||||
postdrop:x:90:
|
||||
postfix:x:89:
|
||||
chrony:x:996:
|
||||
joeuser:x:1000:joeuser
|
||||
cgred:x:995:
|
||||
dockerroot:x:994:
|
||||
1
tests/fixtures/centos-7.7/gshadow.json
vendored
Normal file
1
tests/fixtures/centos-7.7/gshadow.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"group_name": "root", "password": "", "administrators": [], "members": []}, {"group_name": "bin", "password": "", "administrators": [], "members": []}, {"group_name": "daemon", "password": "", "administrators": [], "members": []}, {"group_name": "sys", "password": "", "administrators": [], "members": []}, {"group_name": "adm", "password": "", "administrators": [], "members": []}, {"group_name": "tty", "password": "", "administrators": [], "members": []}, {"group_name": "disk", "password": "", "administrators": [], "members": []}, {"group_name": "lp", "password": "", "administrators": [], "members": []}, {"group_name": "mem", "password": "", "administrators": [], "members": []}, {"group_name": "kmem", "password": "", "administrators": [], "members": []}, {"group_name": "wheel", "password": "", "administrators": [], "members": ["joeuser"]}, {"group_name": "cdrom", "password": "", "administrators": [], "members": []}, {"group_name": "mail", "password": "", "administrators": [], "members": ["postfix"]}, {"group_name": "man", "password": "", "administrators": [], "members": []}, {"group_name": "dialout", "password": "", "administrators": [], "members": []}, {"group_name": "floppy", "password": "", "administrators": [], "members": []}, {"group_name": "games", "password": "", "administrators": [], "members": []}, {"group_name": "tape", "password": "", "administrators": [], "members": []}, {"group_name": "video", "password": "", "administrators": [], "members": []}, {"group_name": "ftp", "password": "", "administrators": [], "members": []}, {"group_name": "lock", "password": "", "administrators": [], "members": []}, {"group_name": "audio", "password": "", "administrators": [], "members": []}, {"group_name": "nobody", "password": "", "administrators": [], "members": []}, {"group_name": "users", "password": "", "administrators": [], "members": []}, {"group_name": "utmp", "password": "!", "administrators": [], "members": []}, {"group_name": "utempter", "password": "!", "administrators": [], "members": []}, {"group_name": "input", "password": "!", "administrators": [], "members": []}, {"group_name": "systemd-journal", "password": "!", "administrators": [], "members": []}, {"group_name": "systemd-network", "password": "!", "administrators": [], "members": []}, {"group_name": "dbus", "password": "!", "administrators": [], "members": []}, {"group_name": "polkitd", "password": "!", "administrators": [], "members": []}, {"group_name": "ssh_keys", "password": "!", "administrators": [], "members": []}, {"group_name": "sshd", "password": "!", "administrators": [], "members": []}, {"group_name": "postdrop", "password": "!", "administrators": [], "members": []}, {"group_name": "postfix", "password": "!", "administrators": [], "members": []}, {"group_name": "chrony", "password": "!", "administrators": [], "members": []}, {"group_name": "joeuser", "password": "!!", "administrators": [], "members": ["joeuser"]}, {"group_name": "cgred", "password": "!", "administrators": [], "members": []}, {"group_name": "dockerroot", "password": "!", "administrators": [], "members": []}]
|
||||
39
tests/fixtures/centos-7.7/gshadow.out
vendored
Normal file
39
tests/fixtures/centos-7.7/gshadow.out
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
root:::
|
||||
bin:::
|
||||
daemon:::
|
||||
sys:::
|
||||
adm:::
|
||||
tty:::
|
||||
disk:::
|
||||
lp:::
|
||||
mem:::
|
||||
kmem:::
|
||||
wheel:::joeuser
|
||||
cdrom:::
|
||||
mail:::postfix
|
||||
man:::
|
||||
dialout:::
|
||||
floppy:::
|
||||
games:::
|
||||
tape:::
|
||||
video:::
|
||||
ftp:::
|
||||
lock:::
|
||||
audio:::
|
||||
nobody:::
|
||||
users:::
|
||||
utmp:!::
|
||||
utempter:!::
|
||||
input:!::
|
||||
systemd-journal:!::
|
||||
systemd-network:!::
|
||||
dbus:!::
|
||||
polkitd:!::
|
||||
ssh_keys:!::
|
||||
sshd:!::
|
||||
postdrop:!::
|
||||
postfix:!::
|
||||
chrony:!::
|
||||
joeuser:!!::joeuser
|
||||
cgred:!::
|
||||
dockerroot:!::
|
||||
1
tests/fixtures/centos-7.7/last-w.json
vendored
Normal file
1
tests/fixtures/centos-7.7/last-w.json
vendored
Normal file
File diff suppressed because one or more lines are too long
69
tests/fixtures/centos-7.7/last-w.out
vendored
Normal file
69
tests/fixtures/centos-7.7/last-w.out
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
kbrazil ttyS0 Fri Feb 28 13:49 still logged in
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Fri Feb 28 12:56 - 14:54 (01:58)
|
||||
kbrazil ttyS0 Thu Feb 27 16:01 - crash (20:54)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Thu Feb 27 15:51 - 14:54 (23:02)
|
||||
kbrazil ttyS0 Thu Feb 27 10:50 - crash (05:01)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Wed Feb 26 20:05 - 14:54 (1+18:49)
|
||||
kbrazil ttyS0 Thu Feb 20 14:42 - crash (6+05:23)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Thu Feb 20 14:41 - 14:54 (8+00:12)
|
||||
kbrazil ttyS0 Mon Feb 17 17:48 - crash (2+20:52)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Mon Feb 17 17:48 - 14:54 (10+21:06)
|
||||
kbrazil ttyS0 Thu Feb 13 16:44 - crash (4+01:03)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Thu Feb 13 16:44 - 14:54 (14+22:10)
|
||||
kbrazil ttyS0 Wed Feb 5 14:23 - crash (8+02:20)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Wed Feb 5 11:43 - 14:54 (23+03:11)
|
||||
kbrazil ttyS0 Tue Feb 4 14:28 - crash (21:15)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Tue Feb 4 01:28 - 14:54 (24+13:26)
|
||||
kbrazil ttyS0 Mon Jan 13 17:28 - crash (21+07:59)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Mon Jan 13 16:16 - 14:54 (45+22:38)
|
||||
kbrazil ttyS0 Mon Dec 16 11:15 - crash (28+05:01)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Mon Dec 16 11:14 - 14:54 (74+03:40)
|
||||
kbrazil ttyS0 Wed Dec 4 21:41 - crash (11+13:33)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Wed Dec 4 21:40 - 14:54 (85+17:13)
|
||||
kbrazil pts/1 Sat Nov 16 14:40 - 14:40 (00:00)
|
||||
kbrazil pts/1 Sat Nov 16 14:39 - 14:39 (00:00)
|
||||
kbrazil pts/0 localhost Tue Nov 12 07:19 - crash (22+14:21)
|
||||
kbrazil ttyS0 Tue Nov 12 07:18 - crash (22+14:22)
|
||||
kbrazil pts/0 localhost Sun Nov 10 08:21 - 15:22 (1+07:01)
|
||||
kbrazil ttyS0 Sat Nov 9 10:34 - 07:16 (2+20:42)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Sat Nov 9 10:34 - 14:54 (111+04:20)
|
||||
kbrazil tty1 Fri Nov 8 07:49 - crash (1+02:45)
|
||||
kbrazil pts/0 192.168.71.1 Fri Nov 8 06:29 - crash (1+04:04)
|
||||
kbrazil ttyS0 Fri Nov 8 06:24 - crash (1+04:09)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Fri Nov 8 06:14 - 14:54 (112+08:40)
|
||||
kbrazil tty1 Sun Nov 3 12:20 - crash (4+17:54)
|
||||
kbrazil ttyS0 Sun Nov 3 11:04 - 11:05 (00:01)
|
||||
kbrazil pts/0 192.168.71.1 Sat Nov 2 19:26 - crash (5+11:47)
|
||||
kbrazil ttyS0 Fri Nov 1 15:14 - 11:03 (1+20:49)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Fri Nov 1 15:13 - 14:54 (119+00:41)
|
||||
kbrazil ttyS0 Fri Nov 1 11:16 - 11:36 (00:20)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Fri Nov 1 06:00 - 11:36 (05:36)
|
||||
kbrazil ttyS0 Tue Oct 29 18:17 - crash (2+11:43)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Tue Oct 29 18:16 - 11:36 (2+17:19)
|
||||
kbrazil pts/0 192.168.71.1 Sat Oct 26 09:53 - 15:13 (05:19)
|
||||
kbrazil ttyS0 Fri Oct 25 18:22 - crash (3+23:54)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Fri Oct 25 18:21 - 11:36 (6+17:14)
|
||||
kbrazil ttyS0 Fri Oct 25 17:14 - 18:21 (01:06)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Fri Oct 25 17:13 - 11:36 (6+18:22)
|
||||
kbrazil ttyS0 Fri Oct 25 15:43 - 17:13 (01:29)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Fri Oct 25 13:29 - 17:13 (03:44)
|
||||
kbrazil ttyS0 Mon Oct 21 13:19 - 19:22 (2+06:03)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Mon Oct 21 13:17 - 19:22 (2+06:05)
|
||||
kbrazil ttyS0 Wed Oct 16 03:23 - crash (5+09:54)
|
||||
kbrazil ttyS0 Tue Oct 15 16:49 - 03:23 (10:34)
|
||||
kbrazil ttyS0 Tue Oct 15 10:39 - 16:48 (06:09)
|
||||
reboot system boot 3.10.0-957.27.2.el7.x86_64 Tue Oct 15 10:39 - 19:22 (8+08:43)
|
||||
kbrazil ttyS0 Thu Aug 15 16:05 - 16:05 (00:00)
|
||||
reboot system boot 3.10.0-957.27.2.el7.x86_64 Thu Aug 15 16:05 - 16:05 (00:00)
|
||||
reboot system boot 3.10.0-957.27.2.el7.x86_64 Thu Aug 15 16:00 - 16:05 (00:05)
|
||||
kbrazil ttyS0 Thu Aug 15 14:25 - crash (01:35)
|
||||
reboot system boot 3.10.0-957.27.2.el7.x86_64 Thu Aug 15 14:24 - 16:05 (01:41)
|
||||
kbrazil ttyS0 Thu Aug 15 11:58 - crash (02:25)
|
||||
reboot system boot 3.10.0-957.el7.x86_64 Thu Aug 15 11:58 - 16:05 (04:07)
|
||||
kbrazil ttyS0 Thu Aug 15 11:57 - 11:57 (00:00)
|
||||
reboot system boot 3.10.0-957.el7.x86_64 Thu Aug 15 11:57 - 16:05 (04:08)
|
||||
kbrazil pts/0 192.168.71.1 Thu Aug 15 10:58 - 11:56 (00:58)
|
||||
root tty1 Thu Aug 15 10:57 - 11:56 (00:59)
|
||||
reboot system boot 3.10.0-957.el7.x86_64 Thu Aug 15 10:57 - 11:56 (00:59)
|
||||
|
||||
wtmp begins Thu Aug 15 10:57:06 2019
|
||||
1
tests/fixtures/centos-7.7/last.json
vendored
Normal file
1
tests/fixtures/centos-7.7/last.json
vendored
Normal file
File diff suppressed because one or more lines are too long
69
tests/fixtures/centos-7.7/last.out
vendored
Normal file
69
tests/fixtures/centos-7.7/last.out
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
kbrazil ttyS0 Fri Feb 28 13:49 still logged in
|
||||
reboot system boot 3.10.0-1062.1.2. Fri Feb 28 12:56 - 14:52 (01:56)
|
||||
kbrazil ttyS0 Thu Feb 27 16:01 - crash (20:54)
|
||||
reboot system boot 3.10.0-1062.1.2. Thu Feb 27 15:51 - 14:52 (23:01)
|
||||
kbrazil ttyS0 Thu Feb 27 10:50 - crash (05:01)
|
||||
reboot system boot 3.10.0-1062.1.2. Wed Feb 26 20:05 - 14:52 (1+18:47)
|
||||
kbrazil ttyS0 Thu Feb 20 14:42 - crash (6+05:23)
|
||||
reboot system boot 3.10.0-1062.1.2. Thu Feb 20 14:41 - 14:52 (8+00:11)
|
||||
kbrazil ttyS0 Mon Feb 17 17:48 - crash (2+20:52)
|
||||
reboot system boot 3.10.0-1062.1.2. Mon Feb 17 17:48 - 14:52 (10+21:04)
|
||||
kbrazil ttyS0 Thu Feb 13 16:44 - crash (4+01:03)
|
||||
reboot system boot 3.10.0-1062.1.2. Thu Feb 13 16:44 - 14:52 (14+22:08)
|
||||
kbrazil ttyS0 Wed Feb 5 14:23 - crash (8+02:20)
|
||||
reboot system boot 3.10.0-1062.1.2. Wed Feb 5 11:43 - 14:52 (23+03:09)
|
||||
kbrazil ttyS0 Tue Feb 4 14:28 - crash (21:15)
|
||||
reboot system boot 3.10.0-1062.1.2. Tue Feb 4 01:28 - 14:52 (24+13:24)
|
||||
kbrazil ttyS0 Mon Jan 13 17:28 - crash (21+07:59)
|
||||
reboot system boot 3.10.0-1062.1.2. Mon Jan 13 16:16 - 14:52 (45+22:36)
|
||||
kbrazil ttyS0 Mon Dec 16 11:15 - crash (28+05:01)
|
||||
reboot system boot 3.10.0-1062.1.2. Mon Dec 16 11:14 - 14:52 (74+03:38)
|
||||
kbrazil ttyS0 Wed Dec 4 21:41 - crash (11+13:33)
|
||||
reboot system boot 3.10.0-1062.1.2. Wed Dec 4 21:40 - 14:52 (85+17:12)
|
||||
kbrazil pts/1 Sat Nov 16 14:40 - 14:40 (00:00)
|
||||
kbrazil pts/1 Sat Nov 16 14:39 - 14:39 (00:00)
|
||||
kbrazil pts/0 localhost Tue Nov 12 07:19 - crash (22+14:21)
|
||||
kbrazil ttyS0 Tue Nov 12 07:18 - crash (22+14:22)
|
||||
kbrazil pts/0 localhost Sun Nov 10 08:21 - 15:22 (1+07:01)
|
||||
kbrazil ttyS0 Sat Nov 9 10:34 - 07:16 (2+20:42)
|
||||
reboot system boot 3.10.0-1062.1.2. Sat Nov 9 10:34 - 14:52 (111+04:18)
|
||||
kbrazil tty1 Fri Nov 8 07:49 - crash (1+02:45)
|
||||
kbrazil pts/0 192.168.71.1 Fri Nov 8 06:29 - crash (1+04:04)
|
||||
kbrazil ttyS0 Fri Nov 8 06:24 - crash (1+04:09)
|
||||
reboot system boot 3.10.0-1062.1.2. Fri Nov 8 06:14 - 14:52 (112+08:38)
|
||||
kbrazil tty1 Sun Nov 3 12:20 - crash (4+17:54)
|
||||
kbrazil ttyS0 Sun Nov 3 11:04 - 11:05 (00:01)
|
||||
kbrazil pts/0 192.168.71.1 Sat Nov 2 19:26 - crash (5+11:47)
|
||||
kbrazil ttyS0 Fri Nov 1 15:14 - 11:03 (1+20:49)
|
||||
reboot system boot 3.10.0-1062.1.2. Fri Nov 1 15:13 - 14:52 (119+00:39)
|
||||
kbrazil ttyS0 Fri Nov 1 11:16 - 11:36 (00:20)
|
||||
reboot system boot 3.10.0-1062.1.2. Fri Nov 1 06:00 - 11:36 (05:36)
|
||||
kbrazil ttyS0 Tue Oct 29 18:17 - crash (2+11:43)
|
||||
reboot system boot 3.10.0-1062.1.2. Tue Oct 29 18:16 - 11:36 (2+17:19)
|
||||
kbrazil pts/0 192.168.71.1 Sat Oct 26 09:53 - 15:13 (05:19)
|
||||
kbrazil ttyS0 Fri Oct 25 18:22 - crash (3+23:54)
|
||||
reboot system boot 3.10.0-1062.1.2. Fri Oct 25 18:21 - 11:36 (6+17:14)
|
||||
kbrazil ttyS0 Fri Oct 25 17:14 - 18:21 (01:06)
|
||||
reboot system boot 3.10.0-1062.1.2. Fri Oct 25 17:13 - 11:36 (6+18:22)
|
||||
kbrazil ttyS0 Fri Oct 25 15:43 - 17:13 (01:29)
|
||||
reboot system boot 3.10.0-1062.1.2. Fri Oct 25 13:29 - 17:13 (03:44)
|
||||
kbrazil ttyS0 Mon Oct 21 13:19 - 19:22 (2+06:03)
|
||||
reboot system boot 3.10.0-1062.1.2. Mon Oct 21 13:17 - 19:22 (2+06:05)
|
||||
kbrazil ttyS0 Wed Oct 16 03:23 - crash (5+09:54)
|
||||
kbrazil ttyS0 Tue Oct 15 16:49 - 03:23 (10:34)
|
||||
kbrazil ttyS0 Tue Oct 15 10:39 - 16:48 (06:09)
|
||||
reboot system boot 3.10.0-957.27.2. Tue Oct 15 10:39 - 19:22 (8+08:43)
|
||||
kbrazil ttyS0 Thu Aug 15 16:05 - 16:05 (00:00)
|
||||
reboot system boot 3.10.0-957.27.2. Thu Aug 15 16:05 - 16:05 (00:00)
|
||||
reboot system boot 3.10.0-957.27.2. Thu Aug 15 16:00 - 16:05 (00:05)
|
||||
kbrazil ttyS0 Thu Aug 15 14:25 - crash (01:35)
|
||||
reboot system boot 3.10.0-957.27.2. Thu Aug 15 14:24 - 16:05 (01:41)
|
||||
kbrazil ttyS0 Thu Aug 15 11:58 - crash (02:25)
|
||||
reboot system boot 3.10.0-957.el7.x Thu Aug 15 11:58 - 16:05 (04:07)
|
||||
kbrazil ttyS0 Thu Aug 15 11:57 - 11:57 (00:00)
|
||||
reboot system boot 3.10.0-957.el7.x Thu Aug 15 11:57 - 16:05 (04:08)
|
||||
kbrazil pts/0 192.168.71.1 Thu Aug 15 10:58 - 11:56 (00:58)
|
||||
root tty1 Thu Aug 15 10:57 - 11:56 (00:59)
|
||||
reboot system boot 3.10.0-957.el7.x Thu Aug 15 10:57 - 11:56 (00:59)
|
||||
|
||||
wtmp begins Thu Aug 15 10:57:06 2019
|
||||
1
tests/fixtures/centos-7.7/lastb.json
vendored
Normal file
1
tests/fixtures/centos-7.7/lastb.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"user": "kbrazil", "tty": "ttyS0", "hostname": null, "login": "Fri Feb 28 13:49", "logout": "13:49", "duration": "00:00"}, {"user": "kbrazil", "tty": "ssh:notty", "hostname": "192.168.71.1", "login": "Thu Feb 27 10:13", "logout": "10:13", "duration": "00:00"}, {"user": "kbrazil", "tty": "ttyS0", "hostname": null, "login": "Thu Feb 20 14:41", "logout": "14:41", "duration": "00:00"}, {"user": "kbrazil", "tty": "ttyS0", "hostname": null, "login": "Mon Feb 17 17:48", "logout": "17:48", "duration": "00:00"}]
|
||||
6
tests/fixtures/centos-7.7/lastb.out
vendored
Normal file
6
tests/fixtures/centos-7.7/lastb.out
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
kbrazil ttyS0 Fri Feb 28 13:49 - 13:49 (00:00)
|
||||
kbrazil ssh:notty 192.168.71.1 Thu Feb 27 10:13 - 10:13 (00:00)
|
||||
kbrazil ttyS0 Thu Feb 20 14:41 - 14:41 (00:00)
|
||||
kbrazil ttyS0 Mon Feb 17 17:48 - 17:48 (00:00)
|
||||
|
||||
btmp begins Mon Feb 17 17:48:53 2020
|
||||
1
tests/fixtures/centos-7.7/ls-R-newlines.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-R-newlines.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"filename": "systemd-private-016de60725a3426792b93fc9f120b8f0-chronyd.service-oZqq4u", "parent": "."}, {"filename": "systemd-private-a30a5a178daa4042b42dfaf5ff9e5f68-chronyd.service-a1tpxv", "parent": "."}, {"filename": "systemd-private-af69d7360f3e40cfa947358c0fb5a6f8-chronyd.service-T3MQ4j", "parent": "."}, {"filename": "tmp.CvALl2jE6u", "parent": "."}, {"filename": "tmp.e7AlxSxY5a", "parent": "."}, {"filename": "tmp.uXm9yegjwj", "parent": "."}, {"filename": "a regular filename", "parent": "./lstest"}, {"filename": "this file has", "parent": "./lstest"}, {"filename": "a combination", "parent": "./lstest"}, {"filename": "of everything", "parent": "./lstest"}, {"filename": "this file has", "parent": "./lstest"}, {"filename": "a newline inside", "parent": "./lstest"}, {"filename": "this file has", "parent": "./lstest"}, {"filename": "four contiguous newlines inside", "parent": "./lstest"}, {"filename": "this file", "parent": "./lstest"}, {"filename": "has", "parent": "./lstest"}, {"filename": "six", "parent": "./lstest"}, {"filename": "newlines", "parent": "./lstest"}, {"filename": "within", "parent": "./lstest"}, {"filename": "this file starts with four newlines", "parent": "./lstest"}, {"filename": "this file starts with one newline", "parent": "./lstest"}]
|
||||
43
tests/fixtures/centos-7.7/ls-R-newlines.out
vendored
Normal file
43
tests/fixtures/centos-7.7/ls-R-newlines.out
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
.:
|
||||
lstest
|
||||
systemd-private-016de60725a3426792b93fc9f120b8f0-chronyd.service-oZqq4u
|
||||
systemd-private-a30a5a178daa4042b42dfaf5ff9e5f68-chronyd.service-a1tpxv
|
||||
systemd-private-af69d7360f3e40cfa947358c0fb5a6f8-chronyd.service-T3MQ4j
|
||||
tmp.CvALl2jE6u
|
||||
tmp.e7AlxSxY5a
|
||||
tmp.uXm9yegjwj
|
||||
|
||||
./lstest:
|
||||
a regular filename
|
||||
|
||||
|
||||
this file has
|
||||
a combination
|
||||
|
||||
|
||||
of everything
|
||||
|
||||
|
||||
|
||||
|
||||
this file has
|
||||
a newline inside
|
||||
this file has
|
||||
|
||||
|
||||
|
||||
four contiguous newlines inside
|
||||
this file
|
||||
has
|
||||
six
|
||||
|
||||
newlines
|
||||
|
||||
within
|
||||
|
||||
|
||||
|
||||
|
||||
this file starts with four newlines
|
||||
|
||||
this file starts with one newline
|
||||
1
tests/fixtures/centos-7.7/ls-R.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-R.json
vendored
Normal file
File diff suppressed because one or more lines are too long
5089
tests/fixtures/centos-7.7/ls-R.out
vendored
Normal file
5089
tests/fixtures/centos-7.7/ls-R.out
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
tests/fixtures/centos-7.7/ls-alR.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-alR.json
vendored
Normal file
File diff suppressed because one or more lines are too long
4997
tests/fixtures/centos-7.7/ls-alR.out
vendored
Normal file
4997
tests/fixtures/centos-7.7/ls-alR.out
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
tests/fixtures/centos-7.7/ls-glob.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-glob.json
vendored
Normal file
File diff suppressed because one or more lines are too long
1919
tests/fixtures/centos-7.7/ls-glob.out
vendored
Normal file
1919
tests/fixtures/centos-7.7/ls-glob.out
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
tests/fixtures/centos-7.7/ls-l-newlines.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-l-newlines.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"filename": "a regular filename", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:12"}, {"filename": "\n\nthis file has\na combination\n\n\nof everything\n\n\n\n", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:17"}, {"filename": "this file has\na newline inside", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:14"}, {"filename": "this file has\n\n\n\nfour contiguous newlines inside", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:14"}, {"filename": "this file\nhas\nsix\n\nnewlines\n\nwithin", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:16"}, {"filename": "\n\n\n\nthis file starts with four newlines", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:40"}, {"filename": "\nthis file starts with one newline", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:13"}]
|
||||
34
tests/fixtures/centos-7.7/ls-l-newlines.out
vendored
Normal file
34
tests/fixtures/centos-7.7/ls-l-newlines.out
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
total 0
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:12 a regular filename
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:17
|
||||
|
||||
this file has
|
||||
a combination
|
||||
|
||||
|
||||
of everything
|
||||
|
||||
|
||||
|
||||
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:14 this file has
|
||||
a newline inside
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:14 this file has
|
||||
|
||||
|
||||
|
||||
four contiguous newlines inside
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:16 this file
|
||||
has
|
||||
six
|
||||
|
||||
newlines
|
||||
|
||||
within
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:40
|
||||
|
||||
|
||||
|
||||
this file starts with four newlines
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:13
|
||||
this file starts with one newline
|
||||
1
tests/fixtures/centos-7.7/ls-lR-newlines.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-lR-newlines.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"filename": "lstest", "parent": ".", "flags": "drwxrwxr-x.", "links": 2, "owner": "kbrazil", "group": "kbrazil", "size": 4096, "date": "Feb 22 00:40"}, {"filename": "systemd-private-016de60725a3426792b93fc9f120b8f0-chronyd.service-oZqq4u", "parent": ".", "flags": "drwx------.", "links": 3, "owner": "root", "group": "root", "size": 17, "date": "Feb 13 16:44"}, {"filename": "systemd-private-a30a5a178daa4042b42dfaf5ff9e5f68-chronyd.service-a1tpxv", "parent": ".", "flags": "drwx------.", "links": 3, "owner": "root", "group": "root", "size": 17, "date": "Feb 17 17:48"}, {"filename": "systemd-private-af69d7360f3e40cfa947358c0fb5a6f8-chronyd.service-T3MQ4j", "parent": ".", "flags": "drwx------.", "links": 3, "owner": "root", "group": "root", "size": 17, "date": "Feb 20 14:41"}, {"filename": "tmp.CvALl2jE6u", "parent": ".", "flags": "drwx------.", "links": 2, "owner": "root", "group": "root", "size": 6, "date": "Feb 13 16:44"}, {"filename": "tmp.e7AlxSxY5a", "parent": ".", "flags": "drwx------.", "links": 2, "owner": "root", "group": "root", "size": 6, "date": "Feb 20 14:41"}, {"filename": "tmp.uXm9yegjwj", "parent": ".", "flags": "drwx------.", "links": 2, "owner": "root", "group": "root", "size": 6, "date": "Feb 17 17:48"}, {"filename": "a regular filename", "parent": "./lstest", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:12"}, {"filename": "\n\nthis file has\na combination\n\n\nof everything\n\n\n\n", "parent": "./lstest", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:17"}, {"filename": "this file has\na newline inside", "parent": "./lstest", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:14"}, {"filename": "this file has\n\n\n\nfour contiguous newlines inside", "parent": "./lstest", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:14"}, {"filename": "this file\nhas\nsix\n\nnewlines\n\nwithin", "parent": "./lstest", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:16"}, {"filename": "\n\n\n\nthis file starts with four newlines", "parent": "./lstest", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:40"}, {"filename": "\nthis file starts with one newline", "parent": "./lstest", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:13"}]
|
||||
45
tests/fixtures/centos-7.7/ls-lR-newlines.out
vendored
Normal file
45
tests/fixtures/centos-7.7/ls-lR-newlines.out
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
.:
|
||||
total 4
|
||||
drwxrwxr-x. 2 kbrazil kbrazil 4096 Feb 22 00:40 lstest
|
||||
drwx------. 3 root root 17 Feb 13 16:44 systemd-private-016de60725a3426792b93fc9f120b8f0-chronyd.service-oZqq4u
|
||||
drwx------. 3 root root 17 Feb 17 17:48 systemd-private-a30a5a178daa4042b42dfaf5ff9e5f68-chronyd.service-a1tpxv
|
||||
drwx------. 3 root root 17 Feb 20 14:41 systemd-private-af69d7360f3e40cfa947358c0fb5a6f8-chronyd.service-T3MQ4j
|
||||
drwx------. 2 root root 6 Feb 13 16:44 tmp.CvALl2jE6u
|
||||
drwx------. 2 root root 6 Feb 20 14:41 tmp.e7AlxSxY5a
|
||||
drwx------. 2 root root 6 Feb 17 17:48 tmp.uXm9yegjwj
|
||||
|
||||
./lstest:
|
||||
total 0
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:12 a regular filename
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:17
|
||||
|
||||
this file has
|
||||
a combination
|
||||
|
||||
|
||||
of everything
|
||||
|
||||
|
||||
|
||||
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:14 this file has
|
||||
a newline inside
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:14 this file has
|
||||
|
||||
|
||||
|
||||
four contiguous newlines inside
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:16 this file
|
||||
has
|
||||
six
|
||||
|
||||
newlines
|
||||
|
||||
within
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:40
|
||||
|
||||
|
||||
|
||||
this file starts with four newlines
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:13
|
||||
this file starts with one newline
|
||||
1
tests/fixtures/centos-7.7/ls-newlines.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-newlines.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"filename": "a regular filename"}, {"filename": "this file has"}, {"filename": "a combination"}, {"filename": "of everything"}, {"filename": "this file has"}, {"filename": "a newline inside"}, {"filename": "this file has"}, {"filename": "four contiguous newlines inside"}, {"filename": "this file"}, {"filename": "has"}, {"filename": "six"}, {"filename": "newlines"}, {"filename": "within"}, {"filename": "this file starts with four newlines"}, {"filename": "this file starts with one newline"}]
|
||||
33
tests/fixtures/centos-7.7/ls-newlines.out
vendored
Normal file
33
tests/fixtures/centos-7.7/ls-newlines.out
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
a regular filename
|
||||
|
||||
|
||||
this file has
|
||||
a combination
|
||||
|
||||
|
||||
of everything
|
||||
|
||||
|
||||
|
||||
|
||||
this file has
|
||||
a newline inside
|
||||
this file has
|
||||
|
||||
|
||||
|
||||
four contiguous newlines inside
|
||||
this file
|
||||
has
|
||||
six
|
||||
|
||||
newlines
|
||||
|
||||
within
|
||||
|
||||
|
||||
|
||||
|
||||
this file starts with four newlines
|
||||
|
||||
this file starts with one newline
|
||||
1
tests/fixtures/centos-7.7/ntpq-p.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ntpq-p.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"state": null, "remote": "44.190.6.254", "refid": "127.67.113.92", "st": 2, "t": "u", "when": 1, "poll": 64, "reach": 1, "delay": 23.399, "offset": -2.805, "jitter": 2.131}, {"state": null, "remote": "ntp.wdc1.us.lea", "refid": "130.133.1.10", "st": 2, "t": "u", "when": null, "poll": 64, "reach": 1, "delay": 93.053, "offset": -0.807, "jitter": 2.839}, {"state": null, "remote": "clock.team-cymr", "refid": "204.9.54.119", "st": 2, "t": "u", "when": null, "poll": 64, "reach": 1, "delay": 70.337, "offset": -2.909, "jitter": 2.6}, {"state": null, "remote": "mirror1.sjc02.s", "refid": "216.218.254.202", "st": 2, "t": "u", "when": 2, "poll": 64, "reach": 1, "delay": 29.325, "offset": 1.044, "jitter": 4.069}]
|
||||
6
tests/fixtures/centos-7.7/ntpq-p.out
vendored
Normal file
6
tests/fixtures/centos-7.7/ntpq-p.out
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
remote refid st t when poll reach delay offset jitter
|
||||
==============================================================================
|
||||
44.190.6.254 127.67.113.92 2 u 1 64 1 23.399 -2.805 2.131
|
||||
ntp.wdc1.us.lea 130.133.1.10 2 u - 64 1 93.053 -0.807 2.839
|
||||
clock.team-cymr 204.9.54.119 2 u - 64 1 70.337 -2.909 2.600
|
||||
mirror1.sjc02.s 216.218.254.202 2 u 2 64 1 29.325 1.044 4.069
|
||||
1
tests/fixtures/centos-7.7/ntpq-pn.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ntpq-pn.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"state": "+", "remote": "44.190.6.254", "refid": "127.67.113.92", "st": 2, "t": "u", "when": 66, "poll": 64, "reach": 377, "delay": 22.69, "offset": -0.392, "jitter": 2.085}, {"state": "-", "remote": "108.59.2.24", "refid": "130.133.1.10", "st": 2, "t": "u", "when": 63, "poll": 64, "reach": 377, "delay": 90.805, "offset": 2.84, "jitter": 1.908}, {"state": "+", "remote": "38.229.71.1", "refid": "204.9.54.119", "st": 2, "t": "u", "when": 64, "poll": 64, "reach": 377, "delay": 68.699, "offset": -0.61, "jitter": 2.576}, {"state": "*", "remote": "72.5.72.15", "refid": "216.218.254.202", "st": 2, "t": "u", "when": 63, "poll": 64, "reach": 377, "delay": 22.654, "offset": 0.231, "jitter": 1.964}]
|
||||
6
tests/fixtures/centos-7.7/ntpq-pn.out
vendored
Normal file
6
tests/fixtures/centos-7.7/ntpq-pn.out
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
remote refid st t when poll reach delay offset jitter
|
||||
==============================================================================
|
||||
+44.190.6.254 127.67.113.92 2 u 66 64 377 22.690 -0.392 2.085
|
||||
-108.59.2.24 130.133.1.10 2 u 63 64 377 90.805 2.840 1.908
|
||||
+38.229.71.1 204.9.54.119 2 u 64 64 377 68.699 -0.610 2.576
|
||||
*72.5.72.15 216.218.254.202 2 u 63 64 377 22.654 0.231 1.964
|
||||
1
tests/fixtures/centos-7.7/passwd.json
vendored
Normal file
1
tests/fixtures/centos-7.7/passwd.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"username": "root", "password": "x", "uid": 0, "gid": 0, "comment": "root", "home": "/root", "shell": "/bin/bash"}, {"username": "bin", "password": "x", "uid": 1, "gid": 1, "comment": "bin", "home": "/bin", "shell": "/sbin/nologin"}, {"username": "daemon", "password": "x", "uid": 2, "gid": 2, "comment": "daemon", "home": "/sbin", "shell": "/sbin/nologin"}, {"username": "adm", "password": "x", "uid": 3, "gid": 4, "comment": "adm", "home": "/var/adm", "shell": "/sbin/nologin"}, {"username": "lp", "password": "x", "uid": 4, "gid": 7, "comment": "lp", "home": "/var/spool/lpd", "shell": "/sbin/nologin"}, {"username": "sync", "password": "x", "uid": 5, "gid": 0, "comment": "sync", "home": "/sbin", "shell": "/bin/sync"}, {"username": "shutdown", "password": "x", "uid": 6, "gid": 0, "comment": "shutdown", "home": "/sbin", "shell": "/sbin/shutdown"}, {"username": "halt", "password": "x", "uid": 7, "gid": 0, "comment": "halt", "home": "/sbin", "shell": "/sbin/halt"}, {"username": "mail", "password": "x", "uid": 8, "gid": 12, "comment": "mail", "home": "/var/spool/mail", "shell": "/sbin/nologin"}, {"username": "operator", "password": "x", "uid": 11, "gid": 0, "comment": "operator", "home": "/root", "shell": "/sbin/nologin"}, {"username": "games", "password": "x", "uid": 12, "gid": 100, "comment": "games", "home": "/usr/games", "shell": "/sbin/nologin"}, {"username": "ftp", "password": "x", "uid": 14, "gid": 50, "comment": "FTP User", "home": "/var/ftp", "shell": "/sbin/nologin"}, {"username": "nobody", "password": "x", "uid": 99, "gid": 99, "comment": "Nobody", "home": "/", "shell": "/sbin/nologin"}, {"username": "systemd-network", "password": "x", "uid": 192, "gid": 192, "comment": "systemd Network Management", "home": "/", "shell": "/sbin/nologin"}, {"username": "dbus", "password": "x", "uid": 81, "gid": 81, "comment": "System message bus", "home": "/", "shell": "/sbin/nologin"}, {"username": "polkitd", "password": "x", "uid": 999, "gid": 998, "comment": "User for polkitd", "home": "/", "shell": "/sbin/nologin"}, {"username": "sshd", "password": "x", "uid": 74, "gid": 74, "comment": "Privilege-separated SSH", "home": "/var/empty/sshd", "shell": "/sbin/nologin"}, {"username": "postfix", "password": "x", "uid": 89, "gid": 89, "comment": "", "home": "/var/spool/postfix", "shell": "/sbin/nologin"}, {"username": "chrony", "password": "x", "uid": 998, "gid": 996, "comment": "", "home": "/var/lib/chrony", "shell": "/sbin/nologin"}, {"username": "joeuser", "password": "x", "uid": 1000, "gid": 1000, "comment": "joeuser", "home": "/home/joeuser", "shell": "/bin/bash"}, {"username": "dockerroot", "password": "x", "uid": 997, "gid": 994, "comment": "Docker User", "home": "/var/lib/docker", "shell": "/sbin/nologin"}]
|
||||
21
tests/fixtures/centos-7.7/passwd.out
vendored
Normal file
21
tests/fixtures/centos-7.7/passwd.out
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
root:x:0:0:root:/root:/bin/bash
|
||||
bin:x:1:1:bin:/bin:/sbin/nologin
|
||||
daemon:x:2:2:daemon:/sbin:/sbin/nologin
|
||||
adm:x:3:4:adm:/var/adm:/sbin/nologin
|
||||
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
|
||||
sync:x:5:0:sync:/sbin:/bin/sync
|
||||
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
|
||||
halt:x:7:0:halt:/sbin:/sbin/halt
|
||||
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
|
||||
operator:x:11:0:operator:/root:/sbin/nologin
|
||||
games:x:12:100:games:/usr/games:/sbin/nologin
|
||||
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
|
||||
nobody:x:99:99:Nobody:/:/sbin/nologin
|
||||
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
|
||||
dbus:x:81:81:System message bus:/:/sbin/nologin
|
||||
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
|
||||
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
|
||||
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
|
||||
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
|
||||
joeuser:x:1000:1000:joeuser:/home/joeuser:/bin/bash
|
||||
dockerroot:x:997:994:Docker User:/var/lib/docker:/sbin/nologin
|
||||
1
tests/fixtures/centos-7.7/shadow.json
vendored
Normal file
1
tests/fixtures/centos-7.7/shadow.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"username": "root", "password": "$6$27lBiByDWdiM7lvJ$ulWkJyfKNbqDnrIKPLhUCGanKcS5TdY3ZasKMR/v2dl0mHn0s28LcxTXMqqOV0d6tww0U4gmgYZezgAf/F8Pz.", "last_changed": null, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "bin", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "daemon", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "adm", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "lp", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "sync", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "shutdown", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "halt", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "mail", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "operator", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "games", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "ftp", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "nobody", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "systemd-network", "password": "!!", "last_changed": 18123, "minimum": null, "maximum": null, "warn": null, "inactive": null, "expire": null}, {"username": "dbus", "password": "!!", "last_changed": 18123, "minimum": null, "maximum": null, "warn": null, "inactive": null, "expire": null}, {"username": "polkitd", "password": "!!", "last_changed": 18123, "minimum": null, "maximum": null, "warn": null, "inactive": null, "expire": null}, {"username": "sshd", "password": "!!", "last_changed": 18123, "minimum": null, "maximum": null, "warn": null, "inactive": null, "expire": null}, {"username": "postfix", "password": "!!", "last_changed": 18123, "minimum": null, "maximum": null, "warn": null, "inactive": null, "expire": null}, {"username": "chrony", "password": "!!", "last_changed": 18123, "minimum": null, "maximum": null, "warn": null, "inactive": null, "expire": null}, {"username": "joeuser", "password": "$6$sR1OEFM1KVuMeBUt$NhanSmm91.BspCYlMtrjYhc71FElgaCP7uSUAwhtQVFGcYa7.8VPMmRce77yS8FLy6XSYBtcCeZCJhnLOicc/.", "last_changed": null, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "dockerroot", "password": "!!", "last_changed": 18123, "minimum": null, "maximum": null, "warn": null, "inactive": null, "expire": null}]
|
||||
21
tests/fixtures/centos-7.7/shadow.out
vendored
Normal file
21
tests/fixtures/centos-7.7/shadow.out
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
root:$6$27lBiByDWdiM7lvJ$ulWkJyfKNbqDnrIKPLhUCGanKcS5TdY3ZasKMR/v2dl0mHn0s28LcxTXMqqOV0d6tww0U4gmgYZezgAf/F8Pz.::0:99999:7:::
|
||||
bin:*:17834:0:99999:7:::
|
||||
daemon:*:17834:0:99999:7:::
|
||||
adm:*:17834:0:99999:7:::
|
||||
lp:*:17834:0:99999:7:::
|
||||
sync:*:17834:0:99999:7:::
|
||||
shutdown:*:17834:0:99999:7:::
|
||||
halt:*:17834:0:99999:7:::
|
||||
mail:*:17834:0:99999:7:::
|
||||
operator:*:17834:0:99999:7:::
|
||||
games:*:17834:0:99999:7:::
|
||||
ftp:*:17834:0:99999:7:::
|
||||
nobody:*:17834:0:99999:7:::
|
||||
systemd-network:!!:18123::::::
|
||||
dbus:!!:18123::::::
|
||||
polkitd:!!:18123::::::
|
||||
sshd:!!:18123::::::
|
||||
postfix:!!:18123::::::
|
||||
chrony:!!:18123::::::
|
||||
joeuser:$6$sR1OEFM1KVuMeBUt$NhanSmm91.BspCYlMtrjYhc71FElgaCP7uSUAwhtQVFGcYa7.8VPMmRce77yS8FLy6XSYBtcCeZCJhnLOicc/.::0:99999:7:::
|
||||
dockerroot:!!:18123::::::
|
||||
1
tests/fixtures/centos-7.7/timedatectl.json
vendored
Normal file
1
tests/fixtures/centos-7.7/timedatectl.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"local_time": "Tue 2020-03-10 17:53:21 PDT", "universal_time": "Wed 2020-03-11 00:53:21 UTC", "rtc_time": "Wed 2020-03-11 00:53:21", "time_zone": "America/Los_Angeles (PDT, -0700)", "ntp_enabled": true, "ntp_synchronized": true, "rtc_in_local_tz": false, "dst_active": true}
|
||||
14
tests/fixtures/centos-7.7/timedatectl.out
vendored
Normal file
14
tests/fixtures/centos-7.7/timedatectl.out
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
Local time: Tue 2020-03-10 17:53:21 PDT
|
||||
Universal time: Wed 2020-03-11 00:53:21 UTC
|
||||
RTC time: Wed 2020-03-11 00:53:21
|
||||
Time zone: America/Los_Angeles (PDT, -0700)
|
||||
NTP enabled: yes
|
||||
NTP synchronized: yes
|
||||
RTC in local TZ: no
|
||||
DST active: yes
|
||||
Last DST change: DST began at
|
||||
Sun 2020-03-08 01:59:59 PST
|
||||
Sun 2020-03-08 03:00:00 PDT
|
||||
Next DST change: DST ends (the clock jumps one hour backwards) at
|
||||
Sun 2020-11-01 01:59:59 PDT
|
||||
Sun 2020-11-01 01:00:00 PST
|
||||
1
tests/fixtures/centos-7.7/who-a.json
vendored
Normal file
1
tests/fixtures/centos-7.7/who-a.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"event": "reboot", "time": "2020-02-29 12:13"}, {"event": "login", "tty": "tty1", "time": "2020-02-29 12:13", "pid": 841, "comment": "id=tty1"}, {"user": "kbrazil", "writeable_tty": "+", "tty": "ttyS0", "time": "2020-02-29 12:14", "idle": ".", "pid": 840}, {"event": "run-level 3", "time": "2020-02-29 12:13"}, {"user": "kbrazil", "writeable_tty": "+", "tty": "pts/0", "time": "2020-02-29 18:43", "idle": "00:11", "pid": 3709, "from": "192.168.71.1"}, {"tty": "pts/1", "time": "2020-02-29 18:28", "pid": 3381, "comment": "id=ts/1 term=0 exit=0"}]
|
||||
6
tests/fixtures/centos-7.7/who-a.out
vendored
Normal file
6
tests/fixtures/centos-7.7/who-a.out
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
system boot 2020-02-29 12:13
|
||||
LOGIN tty1 2020-02-29 12:13 841 id=tty1
|
||||
kbrazil + ttyS0 2020-02-29 12:14 . 840
|
||||
run-level 3 2020-02-29 12:13
|
||||
kbrazil + pts/0 2020-02-29 18:43 00:11 3709 (192.168.71.1)
|
||||
pts/1 2020-02-29 18:28 3381 id=ts/1 term=0 exit=0
|
||||
1
tests/fixtures/centos-7.7/who.json
vendored
Normal file
1
tests/fixtures/centos-7.7/who.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"user": "kbrazil", "tty": "ttyS0", "time": "2020-02-29 12:14"}, {"user": "kbrazil", "tty": "pts/0", "time": "2020-02-29 18:43", "from": "192.168.71.1"}]
|
||||
2
tests/fixtures/centos-7.7/who.out
vendored
Normal file
2
tests/fixtures/centos-7.7/who.out
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
kbrazil ttyS0 2020-02-29 12:14
|
||||
kbrazil pts/0 2020-02-29 18:43 (192.168.71.1)
|
||||
33
tests/fixtures/create_fixtures.sh
vendored
33
tests/fixtures/create_fixtures.sh
vendored
@@ -35,6 +35,26 @@ jobs > jobs.out
|
||||
ls / > ls.out
|
||||
ls -al / > ls-al.out
|
||||
ls -alh / > ls-alh.out
|
||||
|
||||
ls -R /usr > ls-R.out
|
||||
ls -alR /usr > ls-alR.out
|
||||
ls /usr/* > ls-glob.out
|
||||
|
||||
cd /tmp/lstest
|
||||
touch 'a regular filename'
|
||||
touch $'\nthis file starts with one newline'
|
||||
touch $'\n\n\n\nthis file starts with four newlines'
|
||||
touch $'this file has\na newline inside'
|
||||
touch $'this file has\n\n\n\nfour contiguous newlines inside'
|
||||
touch $'this file\nhas\nsix\n\nnewlines\n\nwithin'
|
||||
touch $'\n\nthis file has\na combination\n\n\nof everything\n\n\n\n'
|
||||
cd /tmp
|
||||
ls -R > ~/utils/ls-R-newlines.out
|
||||
ls -lR > ~/utils/ls-lR-newlines.out
|
||||
cd lstest
|
||||
ls > ~/utils/ls-newlines.out
|
||||
ls -l > ~/utils/ls-l-newlines.out
|
||||
|
||||
lsblk > lsblk.out
|
||||
lsblk -o +KNAME,FSTYPE,LABEL,UUID,PARTLABEL,PARTUUID,RA,MODEL,SERIAL,STATE,OWNER,GROUP,MODE,ALIGNMENT,MIN-IO,OPT-IO,PHY-SEC,LOG-SEC,ROTA,SCHED,RQ-SIZE,DISC-ALN,DISC-GRAN,DISC-MAX,DISC-ZERO,WSAME,WWN,RAND,PKNAME,HCTL,TRAN,REV,VENDOR > lsblk-allcols.out
|
||||
lsmod > lsmod.out
|
||||
@@ -68,3 +88,16 @@ systemctl -a list-jobs > systemctl-jobs.out
|
||||
du /usr > du.out
|
||||
pip3 list > pip-list.out
|
||||
pip3 show wheel pip jc > pip-show.out
|
||||
|
||||
blkid > blkid.out
|
||||
blkid /dev/sda2 > blkid-sda2.out
|
||||
sudo blkid -ip /dev/sda2 /dev/sda1 > blkid-ip-multi.out
|
||||
sudo blkid -o udev -ip /dev/sr0 > blkid-ip-udev.out
|
||||
sudo blkid -o udev -ip /dev/sda2 /dev/sda1 > blkid-ip-udev-multi.out
|
||||
|
||||
last > last.out
|
||||
last -w | cat > last-w.out
|
||||
sudo lastb > lastb.out
|
||||
|
||||
cat /etc/group > group.out
|
||||
sudo cat /etc/gshadow > gshadow.out
|
||||
|
||||
20
tests/fixtures/generic/csv-biostats.csv
vendored
Normal file
20
tests/fixtures/generic/csv-biostats.csv
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
"Name", "Sex", "Age", "Height (in)", "Weight (lbs)"
|
||||
"Alex", "M", 41, 74, 170
|
||||
"Bert", "M", 42, 68, 166
|
||||
"Carl", "M", 32, 70, 155
|
||||
"Dave", "M", 39, 72, 167
|
||||
"Elly", "F", 30, 66, 124
|
||||
"Fran", "F", 33, 66, 115
|
||||
"Gwen", "F", 26, 64, 121
|
||||
"Hank", "M", 30, 71, 158
|
||||
"Ivan", "M", 53, 72, 175
|
||||
"Jake", "M", 32, 69, 143
|
||||
"Kate", "F", 47, 69, 139
|
||||
"Luke", "M", 34, 72, 163
|
||||
"Myra", "F", 23, 62, 98
|
||||
"Neil", "M", 36, 75, 160
|
||||
"Omar", "M", 38, 70, 145
|
||||
"Page", "F", 31, 67, 135
|
||||
"Quin", "M", 29, 71, 176
|
||||
"Ruth", "F", 28, 65, 131
|
||||
|
||||
|
1
tests/fixtures/generic/csv-biostats.json
vendored
Normal file
1
tests/fixtures/generic/csv-biostats.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"Name": "Alex", "Sex": "M", "Age": "41", "Height (in)": "74", "Weight (lbs)": "170"}, {"Name": "Bert", "Sex": "M", "Age": "42", "Height (in)": "68", "Weight (lbs)": "166"}, {"Name": "Carl", "Sex": "M", "Age": "32", "Height (in)": "70", "Weight (lbs)": "155"}, {"Name": "Dave", "Sex": "M", "Age": "39", "Height (in)": "72", "Weight (lbs)": "167"}, {"Name": "Elly", "Sex": "F", "Age": "30", "Height (in)": "66", "Weight (lbs)": "124"}, {"Name": "Fran", "Sex": "F", "Age": "33", "Height (in)": "66", "Weight (lbs)": "115"}, {"Name": "Gwen", "Sex": "F", "Age": "26", "Height (in)": "64", "Weight (lbs)": "121"}, {"Name": "Hank", "Sex": "M", "Age": "30", "Height (in)": "71", "Weight (lbs)": "158"}, {"Name": "Ivan", "Sex": "M", "Age": "53", "Height (in)": "72", "Weight (lbs)": "175"}, {"Name": "Jake", "Sex": "M", "Age": "32", "Height (in)": "69", "Weight (lbs)": "143"}, {"Name": "Kate", "Sex": "F", "Age": "47", "Height (in)": "69", "Weight (lbs)": "139"}, {"Name": "Luke", "Sex": "M", "Age": "34", "Height (in)": "72", "Weight (lbs)": "163"}, {"Name": "Myra", "Sex": "F", "Age": "23", "Height (in)": "62", "Weight (lbs)": "98"}, {"Name": "Neil", "Sex": "M", "Age": "36", "Height (in)": "75", "Weight (lbs)": "160"}, {"Name": "Omar", "Sex": "M", "Age": "38", "Height (in)": "70", "Weight (lbs)": "145"}, {"Name": "Page", "Sex": "F", "Age": "31", "Height (in)": "67", "Weight (lbs)": "135"}, {"Name": "Quin", "Sex": "M", "Age": "29", "Height (in)": "71", "Weight (lbs)": "176"}, {"Name": "Ruth", "Sex": "F", "Age": "28", "Height (in)": "65", "Weight (lbs)": "131"}]
|
||||
130
tests/fixtures/generic/csv-cities.csv
vendored
Normal file
130
tests/fixtures/generic/csv-cities.csv
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
"LatD", "LatM", "LatS", "NS", "LonD", "LonM", "LonS", "EW", "City", "State"
|
||||
41, 5, 59, "N", 80, 39, 0, "W", "Youngstown", OH
|
||||
42, 52, 48, "N", 97, 23, 23, "W", "Yankton", SD
|
||||
46, 35, 59, "N", 120, 30, 36, "W", "Yakima", WA
|
||||
42, 16, 12, "N", 71, 48, 0, "W", "Worcester", MA
|
||||
43, 37, 48, "N", 89, 46, 11, "W", "Wisconsin Dells", WI
|
||||
36, 5, 59, "N", 80, 15, 0, "W", "Winston-Salem", NC
|
||||
49, 52, 48, "N", 97, 9, 0, "W", "Winnipeg", MB
|
||||
39, 11, 23, "N", 78, 9, 36, "W", "Winchester", VA
|
||||
34, 14, 24, "N", 77, 55, 11, "W", "Wilmington", NC
|
||||
39, 45, 0, "N", 75, 33, 0, "W", "Wilmington", DE
|
||||
48, 9, 0, "N", 103, 37, 12, "W", "Williston", ND
|
||||
41, 15, 0, "N", 77, 0, 0, "W", "Williamsport", PA
|
||||
37, 40, 48, "N", 82, 16, 47, "W", "Williamson", WV
|
||||
33, 54, 0, "N", 98, 29, 23, "W", "Wichita Falls", TX
|
||||
37, 41, 23, "N", 97, 20, 23, "W", "Wichita", KS
|
||||
40, 4, 11, "N", 80, 43, 12, "W", "Wheeling", WV
|
||||
26, 43, 11, "N", 80, 3, 0, "W", "West Palm Beach", FL
|
||||
47, 25, 11, "N", 120, 19, 11, "W", "Wenatchee", WA
|
||||
41, 25, 11, "N", 122, 23, 23, "W", "Weed", CA
|
||||
31, 13, 11, "N", 82, 20, 59, "W", "Waycross", GA
|
||||
44, 57, 35, "N", 89, 38, 23, "W", "Wausau", WI
|
||||
42, 21, 36, "N", 87, 49, 48, "W", "Waukegan", IL
|
||||
44, 54, 0, "N", 97, 6, 36, "W", "Watertown", SD
|
||||
43, 58, 47, "N", 75, 55, 11, "W", "Watertown", NY
|
||||
42, 30, 0, "N", 92, 20, 23, "W", "Waterloo", IA
|
||||
41, 32, 59, "N", 73, 3, 0, "W", "Waterbury", CT
|
||||
38, 53, 23, "N", 77, 1, 47, "W", "Washington", DC
|
||||
41, 50, 59, "N", 79, 8, 23, "W", "Warren", PA
|
||||
46, 4, 11, "N", 118, 19, 48, "W", "Walla Walla", WA
|
||||
31, 32, 59, "N", 97, 8, 23, "W", "Waco", TX
|
||||
38, 40, 48, "N", 87, 31, 47, "W", "Vincennes", IN
|
||||
28, 48, 35, "N", 97, 0, 36, "W", "Victoria", TX
|
||||
32, 20, 59, "N", 90, 52, 47, "W", "Vicksburg", MS
|
||||
49, 16, 12, "N", 123, 7, 12, "W", "Vancouver", BC
|
||||
46, 55, 11, "N", 98, 0, 36, "W", "Valley City", ND
|
||||
30, 49, 47, "N", 83, 16, 47, "W", "Valdosta", GA
|
||||
43, 6, 36, "N", 75, 13, 48, "W", "Utica", NY
|
||||
39, 54, 0, "N", 79, 43, 48, "W", "Uniontown", PA
|
||||
32, 20, 59, "N", 95, 18, 0, "W", "Tyler", TX
|
||||
42, 33, 36, "N", 114, 28, 12, "W", "Twin Falls", ID
|
||||
33, 12, 35, "N", 87, 34, 11, "W", "Tuscaloosa", AL
|
||||
34, 15, 35, "N", 88, 42, 35, "W", "Tupelo", MS
|
||||
36, 9, 35, "N", 95, 54, 36, "W", "Tulsa", OK
|
||||
32, 13, 12, "N", 110, 58, 12, "W", "Tucson", AZ
|
||||
37, 10, 11, "N", 104, 30, 36, "W", "Trinidad", CO
|
||||
40, 13, 47, "N", 74, 46, 11, "W", "Trenton", NJ
|
||||
44, 45, 35, "N", 85, 37, 47, "W", "Traverse City", MI
|
||||
43, 39, 0, "N", 79, 22, 47, "W", "Toronto", ON
|
||||
39, 2, 59, "N", 95, 40, 11, "W", "Topeka", KS
|
||||
41, 39, 0, "N", 83, 32, 24, "W", "Toledo", OH
|
||||
33, 25, 48, "N", 94, 3, 0, "W", "Texarkana", TX
|
||||
39, 28, 12, "N", 87, 24, 36, "W", "Terre Haute", IN
|
||||
27, 57, 0, "N", 82, 26, 59, "W", "Tampa", FL
|
||||
30, 27, 0, "N", 84, 16, 47, "W", "Tallahassee", FL
|
||||
47, 14, 24, "N", 122, 25, 48, "W", "Tacoma", WA
|
||||
43, 2, 59, "N", 76, 9, 0, "W", "Syracuse", NY
|
||||
32, 35, 59, "N", 82, 20, 23, "W", "Swainsboro", GA
|
||||
33, 55, 11, "N", 80, 20, 59, "W", "Sumter", SC
|
||||
40, 59, 24, "N", 75, 11, 24, "W", "Stroudsburg", PA
|
||||
37, 57, 35, "N", 121, 17, 24, "W", "Stockton", CA
|
||||
44, 31, 12, "N", 89, 34, 11, "W", "Stevens Point", WI
|
||||
40, 21, 36, "N", 80, 37, 12, "W", "Steubenville", OH
|
||||
40, 37, 11, "N", 103, 13, 12, "W", "Sterling", CO
|
||||
38, 9, 0, "N", 79, 4, 11, "W", "Staunton", VA
|
||||
39, 55, 11, "N", 83, 48, 35, "W", "Springfield", OH
|
||||
37, 13, 12, "N", 93, 17, 24, "W", "Springfield", MO
|
||||
42, 5, 59, "N", 72, 35, 23, "W", "Springfield", MA
|
||||
39, 47, 59, "N", 89, 39, 0, "W", "Springfield", IL
|
||||
47, 40, 11, "N", 117, 24, 36, "W", "Spokane", WA
|
||||
41, 40, 48, "N", 86, 15, 0, "W", "South Bend", IN
|
||||
43, 32, 24, "N", 96, 43, 48, "W", "Sioux Falls", SD
|
||||
42, 29, 24, "N", 96, 23, 23, "W", "Sioux City", IA
|
||||
32, 30, 35, "N", 93, 45, 0, "W", "Shreveport", LA
|
||||
33, 38, 23, "N", 96, 36, 36, "W", "Sherman", TX
|
||||
44, 47, 59, "N", 106, 57, 35, "W", "Sheridan", WY
|
||||
35, 13, 47, "N", 96, 40, 48, "W", "Seminole", OK
|
||||
32, 25, 11, "N", 87, 1, 11, "W", "Selma", AL
|
||||
38, 42, 35, "N", 93, 13, 48, "W", "Sedalia", MO
|
||||
47, 35, 59, "N", 122, 19, 48, "W", "Seattle", WA
|
||||
41, 24, 35, "N", 75, 40, 11, "W", "Scranton", PA
|
||||
41, 52, 11, "N", 103, 39, 36, "W", "Scottsbluff", NB
|
||||
42, 49, 11, "N", 73, 56, 59, "W", "Schenectady", NY
|
||||
32, 4, 48, "N", 81, 5, 23, "W", "Savannah", GA
|
||||
46, 29, 24, "N", 84, 20, 59, "W", "Sault Sainte Marie", MI
|
||||
27, 20, 24, "N", 82, 31, 47, "W", "Sarasota", FL
|
||||
38, 26, 23, "N", 122, 43, 12, "W", "Santa Rosa", CA
|
||||
35, 40, 48, "N", 105, 56, 59, "W", "Santa Fe", NM
|
||||
34, 25, 11, "N", 119, 41, 59, "W", "Santa Barbara", CA
|
||||
33, 45, 35, "N", 117, 52, 12, "W", "Santa Ana", CA
|
||||
37, 20, 24, "N", 121, 52, 47, "W", "San Jose", CA
|
||||
37, 46, 47, "N", 122, 25, 11, "W", "San Francisco", CA
|
||||
41, 27, 0, "N", 82, 42, 35, "W", "Sandusky", OH
|
||||
32, 42, 35, "N", 117, 9, 0, "W", "San Diego", CA
|
||||
34, 6, 36, "N", 117, 18, 35, "W", "San Bernardino", CA
|
||||
29, 25, 12, "N", 98, 30, 0, "W", "San Antonio", TX
|
||||
31, 27, 35, "N", 100, 26, 24, "W", "San Angelo", TX
|
||||
40, 45, 35, "N", 111, 52, 47, "W", "Salt Lake City", UT
|
||||
38, 22, 11, "N", 75, 35, 59, "W", "Salisbury", MD
|
||||
36, 40, 11, "N", 121, 39, 0, "W", "Salinas", CA
|
||||
38, 50, 24, "N", 97, 36, 36, "W", "Salina", KS
|
||||
38, 31, 47, "N", 106, 0, 0, "W", "Salida", CO
|
||||
44, 56, 23, "N", 123, 1, 47, "W", "Salem", OR
|
||||
44, 57, 0, "N", 93, 5, 59, "W", "Saint Paul", MN
|
||||
38, 37, 11, "N", 90, 11, 24, "W", "Saint Louis", MO
|
||||
39, 46, 12, "N", 94, 50, 23, "W", "Saint Joseph", MO
|
||||
42, 5, 59, "N", 86, 28, 48, "W", "Saint Joseph", MI
|
||||
44, 25, 11, "N", 72, 1, 11, "W", "Saint Johnsbury", VT
|
||||
45, 34, 11, "N", 94, 10, 11, "W", "Saint Cloud", MN
|
||||
29, 53, 23, "N", 81, 19, 11, "W", "Saint Augustine", FL
|
||||
43, 25, 48, "N", 83, 56, 24, "W", "Saginaw", MI
|
||||
38, 35, 24, "N", 121, 29, 23, "W", "Sacramento", CA
|
||||
43, 36, 36, "N", 72, 58, 12, "W", "Rutland", VT
|
||||
33, 24, 0, "N", 104, 31, 47, "W", "Roswell", NM
|
||||
35, 56, 23, "N", 77, 48, 0, "W", "Rocky Mount", NC
|
||||
41, 35, 24, "N", 109, 13, 48, "W", "Rock Springs", WY
|
||||
42, 16, 12, "N", 89, 5, 59, "W", "Rockford", IL
|
||||
43, 9, 35, "N", 77, 36, 36, "W", "Rochester", NY
|
||||
44, 1, 12, "N", 92, 27, 35, "W", "Rochester", MN
|
||||
37, 16, 12, "N", 79, 56, 24, "W", "Roanoke", VA
|
||||
37, 32, 24, "N", 77, 26, 59, "W", "Richmond", VA
|
||||
39, 49, 48, "N", 84, 53, 23, "W", "Richmond", IN
|
||||
38, 46, 12, "N", 112, 5, 23, "W", "Richfield", UT
|
||||
45, 38, 23, "N", 89, 25, 11, "W", "Rhinelander", WI
|
||||
39, 31, 12, "N", 119, 48, 35, "W", "Reno", NV
|
||||
50, 25, 11, "N", 104, 39, 0, "W", "Regina", SA
|
||||
40, 10, 48, "N", 122, 14, 23, "W", "Red Bluff", CA
|
||||
40, 19, 48, "N", 75, 55, 48, "W", "Reading", PA
|
||||
41, 9, 35, "N", 81, 14, 23, "W", "Ravenna", OH
|
||||
|
||||
|
1
tests/fixtures/generic/csv-cities.json
vendored
Normal file
1
tests/fixtures/generic/csv-cities.json
vendored
Normal file
File diff suppressed because one or more lines are too long
89
tests/fixtures/generic/csv-deniro.csv
vendored
Normal file
89
tests/fixtures/generic/csv-deniro.csv
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
"Year", "Score", "Title"
|
||||
1968, 86, "Greetings"
|
||||
1970, 17, "Bloody Mama"
|
||||
1970, 73, "Hi, Mom!"
|
||||
1971, 40, "Born to Win"
|
||||
1973, 98, "Mean Streets"
|
||||
1973, 88, "Bang the Drum Slowly"
|
||||
1974, 97, "The Godfather, Part II"
|
||||
1976, 41, "The Last Tycoon"
|
||||
1976, 99, "Taxi Driver"
|
||||
1977, 47, "1900"
|
||||
1977, 67, "New York, New York"
|
||||
1978, 93, "The Deer Hunter"
|
||||
1980, 97, "Raging Bull"
|
||||
1981, 75, "True Confessions"
|
||||
1983, 90, "The King of Comedy"
|
||||
1984, 89, "Once Upon a Time in America"
|
||||
1984, 60, "Falling in Love"
|
||||
1985, 98, "Brazil"
|
||||
1986, 65, "The Mission"
|
||||
1987, 100, "Dear America: Letters Home From Vietnam"
|
||||
1987, 80, "The Untouchables"
|
||||
1987, 78, "Angel Heart"
|
||||
1988, 96, "Midnight Run"
|
||||
1989, 64, "Jacknife"
|
||||
1989, 47, "We're No Angels"
|
||||
1990, 88, "Awakenings"
|
||||
1990, 29, "Stanley & Iris"
|
||||
1990, 96, "Goodfellas"
|
||||
1991, 76, "Cape Fear"
|
||||
1991, 69, "Mistress"
|
||||
1991, 65, "Guilty by Suspicion"
|
||||
1991, 71, "Backdraft"
|
||||
1992, 87, "Thunderheart"
|
||||
1992, 67, "Night and the City"
|
||||
1993, 75, "This Boy's Life"
|
||||
1993, 78, "Mad Dog and Glory"
|
||||
1993, 96, "A Bronx Tale"
|
||||
1994, 39, "Mary Shelley's Frankenstein"
|
||||
1995, 80, "Casino"
|
||||
1995, 86, "Heat"
|
||||
1996, 74, "Sleepers"
|
||||
1996, 38, "The Fan"
|
||||
1996, 80, "Marvin's Room"
|
||||
1997, 85, "Wag the Dog"
|
||||
1997, 87, "Jackie Brown"
|
||||
1997, 72, "Cop Land"
|
||||
1998, 68, "Ronin"
|
||||
1998, 38, "Great Expectations"
|
||||
1999, 69, "Analyze This"
|
||||
1999, 43, "Flawless"
|
||||
2000, 43, "The Adventures of Rocky & Bullwinkle"
|
||||
2000, 84, "Meet the Parents"
|
||||
2000, 41, "Men of Honor"
|
||||
2001, 73, "The Score"
|
||||
2001, 33, "15 Minutes"
|
||||
2002, 48, "City by the Sea"
|
||||
2002, 27, "Analyze That"
|
||||
2003, 4, "Godsend"
|
||||
2004, 35, "Shark Tale"
|
||||
2004, 38, "Meet the Fockers"
|
||||
2005, 4, "The Bridge of San Luis Rey"
|
||||
2005, 46, "Rent"
|
||||
2005, 13, "Hide and Seek"
|
||||
2006, 54, "The Good Shepherd"
|
||||
2007, 21, "Arthur and the Invisibles"
|
||||
2007, 76, "Captain Shakespeare"
|
||||
2008, 19, "Righteous Kill"
|
||||
2008, 51, "What Just Happened?"
|
||||
2009, 46, "Everybody's Fine"
|
||||
2010, 72, "Machete"
|
||||
2010, 10, "Little Fockers"
|
||||
2010, 50, "Stone"
|
||||
2011, 25, "Killer Elite"
|
||||
2011, 7, "New Year's Eve"
|
||||
2011, 70, "Limitless"
|
||||
2012, 92, "Silver Linings Playbook"
|
||||
2012, 51, "Being Flynn"
|
||||
2012, 29, "Red Lights"
|
||||
2013, 46, "Last Vegas"
|
||||
2013, 7, "The Big Wedding"
|
||||
2013, 29, "Grudge Match"
|
||||
2013, 11, "Killing Season"
|
||||
2014, 9, "The Bag Man"
|
||||
2015, 60, "Joy"
|
||||
2015, 26, "Heist"
|
||||
2015, 61, "The Intern"
|
||||
2016, 11, "Dirty Grandpa"
|
||||
|
||||
|
1
tests/fixtures/generic/csv-deniro.json
vendored
Normal file
1
tests/fixtures/generic/csv-deniro.json
vendored
Normal file
File diff suppressed because one or more lines are too long
2
tests/fixtures/generic/csv-example.csv
vendored
Normal file
2
tests/fixtures/generic/csv-example.csv
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
TOK,UPDATE,DATE,SHOT,TIME,AUXHEAT,PHASE,STATE,PGASA,PGASZ,BGASA,BGASZ,BGASA2,BGASZ2,PIMPA,PIMPZ,PELLET,RGEO,RMAG,AMIN,SEPLIM,XPLIM,KAPPA,DELTA,INDENT,AREA,VOL,CONFIG,IGRADB,WALMAT,DIVMAT,LIMMAT,EVAP,BT,IP,VSURF,Q95,BEPMHD,BETMHD,BEPDIA,NEL,DNELDT,ZEFF,PRAD,POHM,ENBI,PINJ,BSOURCE,PINJ2,BSOURCE2,COCTR,PNBI,ECHFREQ,ECHMODE,ECHLOC,PECH,ICFREQ,ICSCHEME,ICANTEN,PICRH,LHFREQ,LHNPAR,PLH,IBWFREQ,PIBW,TE0,TI0,WFANI,WFICRH,MEFF,ISEQ,WTH,WTOT,DWTOT,PL,PLTH,TAUTOT,TAUTH
|
||||
JET,20031201,20001006,53521,1.000E+01,NBIC,HSELM,TRANS,2.000E+00,1.000E+00,2,1,0,0,1.658E+01,8.152E+00,NONE,2.888E+00,3.047E+00,9.807E-01,2.924E-02,7.304E-02,1.572E+00,1.781E-01,0.000E+00,4.572E+00,8.161E+01,LSN,1,IN/C,BE,C/BE,BE,3.598E+00,2.000E+06,1.013E-01,6.001E+00,1.053E+00,9.252E-01,1.128E+00,3.106E+19,3.106E+19,6.612E+00,4.515E+06,5.122E+04,1.000E+05,1.466E+07,771706,0.000E+00,652114,1.000E+00,1.420E+07,-9.999E-09,NONE,NONE,0.000E+00,5.100E+07,HMIN,MONOPOLE,4.027E+06,3.700E+09,1.840E+00,2.000E+06,-9.999E-09,0.000E+00,9.295E+03,1.373E+04,6.913E-01,7.319E+05,2.000E+00,NONE,3.715E+06,5.381E+06,1.282E+06,1.297E+07,1.210E+07,4.445E-01,2.194E-01
|
||||
|
1
tests/fixtures/generic/csv-example.json
vendored
Normal file
1
tests/fixtures/generic/csv-example.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"TOK": "JET", "UPDATE": "20031201", "DATE": "20001006", "SHOT": "53521", "TIME": "1.000E+01", "AUXHEAT": "NBIC", "PHASE": "HSELM", "STATE": "TRANS", "PGASA": "2.000E+00", "PGASZ": "1.000E+00", "BGASA": "2", "BGASZ": "1", "BGASA2": "0", "BGASZ2": "0", "PIMPA": "1.658E+01", "PIMPZ": "8.152E+00", "PELLET": "NONE", "RGEO": "2.888E+00", "RMAG": "3.047E+00", "AMIN": "9.807E-01", "SEPLIM": "2.924E-02", "XPLIM": "7.304E-02", "KAPPA": "1.572E+00", "DELTA": "1.781E-01", "INDENT": "0.000E+00", "AREA": "4.572E+00", "VOL": "8.161E+01", "CONFIG": "LSN", "IGRADB": "1", "WALMAT": "IN/C", "DIVMAT": "BE", "LIMMAT": "C/BE", "EVAP": "BE", "BT": "3.598E+00", "IP": "2.000E+06", "VSURF": "1.013E-01", "Q95": "6.001E+00", "BEPMHD": "1.053E+00", "BETMHD": "9.252E-01", "BEPDIA": "1.128E+00", "NEL": "3.106E+19", "DNELDT": "3.106E+19", "ZEFF": "6.612E+00", "PRAD": "4.515E+06", "POHM": "5.122E+04", "ENBI": "1.000E+05", "PINJ": "1.466E+07", "BSOURCE": "771706", "PINJ2": "0.000E+00", "BSOURCE2": "652114", "COCTR": "1.000E+00", "PNBI": "1.420E+07", "ECHFREQ": "-9.999E-09", "ECHMODE": "NONE", "ECHLOC": "NONE", "PECH": "0.000E+00", "ICFREQ": "5.100E+07", "ICSCHEME": "HMIN", "ICANTEN": "MONOPOLE", "PICRH": "4.027E+06", "LHFREQ": "3.700E+09", "LHNPAR": "1.840E+00", "PLH": "2.000E+06", "IBWFREQ": "-9.999E-09", "PIBW": "0.000E+00", "TE0": "9.295E+03", "TI0": "1.373E+04", "WFANI": "6.913E-01", "WFICRH": "7.319E+05", "MEFF": "2.000E+00", "ISEQ": "NONE", "WTH": "3.715E+06", "WTOT": "5.381E+06", "DWTOT": "1.282E+06", "PL": "1.297E+07", "PLTH": "1.210E+07", "TAUTOT": "4.445E-01", "TAUTH": "2.194E-01"}]
|
||||
1
tests/fixtures/generic/csv-flyrna.json
vendored
Normal file
1
tests/fixtures/generic/csv-flyrna.json
vendored
Normal file
File diff suppressed because one or more lines are too long
11767
tests/fixtures/generic/csv-flyrna.tsv
vendored
Normal file
11767
tests/fixtures/generic/csv-flyrna.tsv
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user