jc Command Reference Guide

Convert Linux command output to JSON — feed anything into jq, Python, or your scripts

Overview

Purpose

jc (JSON Convert) is a command-line tool that converts the output of standard Linux/Unix commands into structured JSON. Instead of writing custom awk or sed parsers for ps, df, netstat, ifconfig, ls, and dozens of other commands, jc parses them for you and outputs clean, consistent JSON that can be piped directly into jq, Python, or any tool that reads JSON.

Basic Syntax

COMMAND | jc --PARSER   —   pipe mode (most common)

jc COMMAND [ARGS]  —  magic syntax mode (jc runs the command)

jc --PARSER < file  —  parse from a saved file

Why This Matters

Unix command output is human-readable text. Scripts that consume it have to parse it — and parsers break when column widths shift, when a hostname is longer than expected, or when output format changes between OS versions. jc absorbs that fragility. Once output is JSON, jq filters it reliably regardless of formatting variations. Your scripts become shorter, more readable, and more robust.

Relationship to jq

jc and jq are natural partners. jc converts command output into JSON. jq queries and transforms JSON. Together they replace most one-off awk/sed parsing scripts. See the jq reference page for the jq side of the pipeline.

Installation

pip (recommended — any distro, always current)

pip3 install jc

# Verify
jc --version
jc --help | head -5

RHEL / CentOS / Fedora

# Fedora
dnf install jc

# RHEL 8/9 via EPEL
dnf install epel-release
dnf install jc

Debian / Ubuntu

apt install jc

List all supported parsers

# Full list — over 100 parsers
jc --list

# Search for a specific command
jc --list | grep ps
jc --list | grep net

Common Options

Option Description
--PARSER Specify the parser: --ps, --df, --ls, etc.
-p Pretty-print JSON output (human-readable with indentation)
-q Quiet — suppress warning messages
-r Raw output — return strings instead of converted types
-u Unbuffered output — useful for streaming/live data
--list List all available parsers
--about Show jc version and info
-a About parser — show details about a specific parser

💡 Pretty-print vs. pipeline

Use -p when you want to read the output yourself. Omit -p when piping to jq — jq handles its own formatting and compact JSON is faster to parse.

10 Detailed Examples

1
Convert ps Output to JSON
# Basic conversion — pretty-printed for reading
ps aux | jc --ps -p

# Pipe into jq to extract just process names and PIDs
ps aux | jc --ps | jq '.[] | {pid, command}'

# Find all processes owned by a specific user
ps aux | jc --ps | jq '.[] | select(.user == "www-data") | {pid, command, cpu_percent}'

# Top 5 processes by CPU
ps aux | jc --ps | jq 'sort_by(.cpu_percent) | reverse | .[:5] | .[] | {pid, command, cpu_percent}'

What This Does:

Converts ps aux text output into a JSON array where each process is an object with named fields: user, pid, cpu_percent, mem_percent, command, and more. No awk field-position parsing required — field names are stable regardless of column width changes.

Sample Output (excerpt):

JSON OUTPUT
[ { "user": "root", "pid": 1, "cpu_percent": 0.0, "mem_percent": 0.1, "vsz": 169100, "rss": 13600, "stat": "Ss", "command": "/usr/lib/systemd/systemd" }, ... ]
2
Disk Usage With df
# Convert df output to JSON
df -h | jc --df -p

# Find filesystems over 80% used
df | jc --df | jq '.[] | select(.use_percent > 80) | {filesystem, use_percent, mounted_on}'

# Just the mount point and available space
df -h | jc --df | jq '.[] | {mounted_on, available}'

# Alert if root filesystem over 90%
df | jc --df | jq '.[] | select(.mounted_on == "/" and .use_percent > 90) | "WARNING: root at \(.use_percent)%"'

What This Does:

Converts df output into JSON with numeric types for use_percent, 1k_blocks, used, and available. Because these are numbers in JSON (not strings), jq can do numeric comparisons directly — no string-stripping of the % sign required.

Practical Application:

Replace the classic df -h | awk '$5 > 80' one-liner with a jc+jq pipeline that is easier to read, extend, and maintain.

3
Network Interface Information With ip
# Parse ip address show output
ip addr | jc --ip-address -p

# Get just interface names and their IP addresses
ip addr | jc --ip-address | jq '.[] | {ifname, addr_info}'

# Find the IP of a specific interface
ip addr | jc --ip-address | jq '.[] | select(.ifname == "eth0") | .addr_info[].local'

# All interfaces that are UP
ip addr | jc --ip-address | jq '.[] | select(.flags[] == "UP") | .ifname'

# Parse ip route output
ip route | jc --ip-route -p

What This Does:

Parses the complex nested output of ip addr into structured JSON with arrays for flags and address info. Extracting an IP address with awk requires careful field counting that breaks on different interface types. jc + jq selects by field name — robust against formatting differences.

Also Available:

  • --ip-route — parse routing table
  • --ip-link — parse link layer info
  • --ss — parse socket statistics (ss command)
4
Parse Log Files — last and who
# Who is currently logged in
who | jc --who -p

# Convert last output to JSON
last | jc --last -p

# Find all logins from a specific user
last | jc --last | jq '.[] | select(.user == "craig") | {user, hostname, started}'

# Find logins from outside the local network
last | jc --last | jq '.[] | select(.hostname | startswith("192.168") | not) | select(.hostname != "") | {user, hostname, started}'

# Count logins per user
last | jc --last | jq 'group_by(.user) | .[] | {user: .[0].user, count: length}' | jq -s 'sort_by(.count) | reverse'

What This Does:

Converts login history from last and current sessions from who into structured JSON. Particularly useful for security auditing — jq filters by hostname pattern to spot logins from unexpected locations, a task that requires multi-step awk in traditional scripting.

SysAdmin Use Case:

Build a daily login audit report: pipe last through jc, filter for off-hours or external logins with jq, format output for email or a ticket.

5
Parse /etc/passwd and /etc/group
# Convert /etc/passwd to JSON
cat /etc/passwd | jc --passwd -p

# Find all users with a real shell (not nologin or false)
cat /etc/passwd | jc --passwd | jq '.[] | select(.shell | test("nologin|false|sync") | not) | {username, uid, shell}'

# Find users with UID above 1000 (regular accounts)
cat /etc/passwd | jc --passwd | jq '.[] | select(.uid >= 1000) | {username, uid, home}'

# Convert /etc/group
cat /etc/group | jc --group -p

# Find which groups a user belongs to
cat /etc/group | jc --group | jq '.[] | select(.members[] == "craig") | .group_name'

What This Does:

Parses the colon-delimited passwd and group files into JSON with proper field names. The members field in group output is a JSON array, making membership queries trivial with jq's select and array operations.

Practical Application:

User audits — find all accounts with login shells, accounts with unusual UIDs, or service accounts that have been granted shell access.

6
System Information — uname, uptime, lsblk
# System info
uname -a | jc --uname -p

# Uptime parsed
uptime | jc --uptime -p

# Block devices
lsblk | jc --lsblk -p

# Find all mounted ext4 filesystems
lsblk | jc --lsblk | jq '.[] | .. | objects | select(.fstype? == "ext4") | {name, size, mountpoint}'

# Combine uname and uptime into one object
echo "{\"system\": $(uname -a | jc --uname), \"uptime\": $(uptime | jc --uptime)}" | jq .

What This Does:

Converts system information commands into clean JSON. The last example shows a useful pattern: constructing a composite JSON object by combining multiple jc outputs inline. This is the foundation of an inventory or health-check script that produces structured output.

Inventory Script Pattern:

Collect uname, uptime, df, ip addr, and ps all through jc, combine into one JSON object, and ship it to a central collector. Structured, machine-readable, no custom parsing required on the receiving end.

7
Parse SSH Known Hosts and Authorized Keys
# Parse known_hosts
cat ~/.ssh/known_hosts | jc --known-hosts-file -p

# List all hostnames in known_hosts
cat ~/.ssh/known_hosts | jc --known-hosts-file | jq '.[].hostnames[]'

# Parse authorized_keys
cat ~/.ssh/authorized_keys | jc --authorized-keys-file -p

# List all key comments (usually username@host)
cat ~/.ssh/authorized_keys | jc --authorized-keys-file | jq '.[].comment'

# Count keys by type
cat ~/.ssh/authorized_keys | jc --authorized-keys-file | jq 'group_by(.key_type) | .[] | {type: .[0].key_type, count: length}'

What This Does:

Parses SSH key files into structured JSON. Useful for security auditing — inventorying all authorized keys across a fleet, checking key types (flagging deprecated RSA-1024 or DSA keys), or verifying known_hosts entries programmatically.

SysAdmin Use Case:

Audit script: loop over all home directories, parse each authorized_keys file through jc, collect into a single JSON array, filter for old key types or keys without comments.

8
Magic Syntax Mode — jc Runs the Command
# jc runs the command and parses output in one step
jc ps aux -p
jc df -h -p
jc ls -la /etc -p
jc netstat -tlnp -p
jc who -p
jc last -p

# Chain directly into jq without an intermediate pipe
jc ps aux | jq '.[] | select(.cpu_percent > 10)'
jc df | jq '.[] | select(.use_percent > 80)'

What This Does:

In magic syntax mode, jc accepts the command and its arguments directly rather than reading from stdin. It runs the command internally and parses the output. The result is slightly shorter syntax for interactive use.

Pipe Mode vs Magic Mode:

  • Pipe: ps aux | jc --ps — explicit, works in scripts, composable
  • Magic: jc ps aux — shorter at the terminal, less explicit
  • Pipe mode is preferred in scripts for clarity and reliability
9
Parse Cron and Systemd
# Parse crontab output
crontab -l | jc --crontab -p

# List all cron commands without the schedule
crontab -l | jc --crontab | jq '.schedule[].command'

# Parse crontab file directly
jc --crontab < /etc/cron.d/myjob -p

# Parse systemctl list-units
systemctl list-units | jc --systemctl -p

# Find all failed units
systemctl list-units | jc --systemctl | jq '.[] | select(.sub == "failed") | .unit'

# Find all active services
systemctl list-units --type=service | jc --systemctl | jq '.[] | select(.active == "active") | .unit'

What This Does:

Converts crontab and systemctl output into structured JSON. Parsing systemctl output with awk is notoriously fragile — unit names, states, and descriptions vary in width and content. jc gives you reliable field names regardless of output formatting.

Practical Application:

Health check script: parse systemctl list-units through jc, filter for failed units with jq, send an alert if the array is non-empty.

10
Building a System Health Report in JSON
#!/bin/bash
# health-report.sh — structured JSON system snapshot
# Requires: jc, jq

HOSTNAME=$(hostname)
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

jq -n \
  --arg host "$HOSTNAME" \
  --arg ts "$TIMESTAMP" \
  --argjson uptime "$(uptime | jc --uptime)" \
  --argjson disk "$(df | jc --df)" \
  --argjson memory "$(free | jc --free)" \
  --argjson top_procs "$(ps aux | jc --ps | jq 'sort_by(.cpu_percent) | reverse | .[:5]')" \
  --argjson failed_units "$(systemctl list-units | jc --systemctl | jq '[.[] | select(.sub == \"failed\")]')" \
  '{
    host: $host,
    timestamp: $ts,
    uptime: $uptime,
    disk: $disk,
    memory: $memory,
    top_processes: $top_procs,
    failed_units: $failed_units
  }'

What This Does:

Builds a complete structured system health report as a single JSON object. Each section (uptime, disk, memory, top processes, failed units) is collected through jc and assembled by jq into one document. The output can be saved to a file, shipped to a monitoring API, stored in Elasticsearch, or compared against a previous snapshot.

💡 jc + jq + AI log analysis

The health report JSON is perfect input for AI log analysis. Pipe the output to sgpt for a plain-English summary: bash health-report.sh | sgpt "Summarize this system health report. Flag anything that needs attention."

⚠️ Parser availability varies

Not every parser is available in every version of jc. If a parser throws an error, check jc --list to confirm it exists in your installed version, then pip3 install --upgrade jc to get the latest parsers. The pip version is always more current than distro packages.

Quick Reference — Common Parsers

Command jc Parser Key Fields
ps aux --ps user, pid, cpu_percent, mem_percent, command
df --df filesystem, use_percent, available, mounted_on
ip addr --ip-address ifname, flags, addr_info[].local
ip route --ip-route route, gateway, dev, metric
last --last user, hostname, started, duration
who --who user, tty, time, hostname
cat /etc/passwd --passwd username, uid, gid, home, shell
cat /etc/group --group group_name, gid, members[]
lsblk --lsblk name, size, type, fstype, mountpoint
uptime --uptime uptime, users, load_1m, load_5m, load_15m
free --free type, total, used, free, available
uname -a --uname kernel_name, node_name, kernel_release, machine
systemctl list-units --systemctl unit, load, active, sub, description
crontab -l --crontab schedule[].minute, hour, command
cat ~/.ssh/authorized_keys --authorized-keys-file key_type, key, comment