JQ
jq is a lightweight command-line JSON processor. It's like sed/awk for JSON data.
BASIC USAGE#
jq '.' file.json # Pretty print JSON
cat file.json | jq '.' # Pipe JSON to jq
echo '{"a":1}' | jq '.' # Parse inline JSON
jq -r '.field' file.json # Raw output (no quotes)
jq -c '.' file.json # Compact output
jq -S '.' file.json # Sort keys
BASIC FILTERS#
jq '.' file.json # Identity (pass through) jq '.field' file.json # Get field value jq '.field1.field2' file.json # Nested field jq '.[0]' file.json # First array element jq '.[-1]' file.json # Last array element jq '.[]' file.json # All array elements jq '.field[]' file.json # All elements in field array
ACCESSING DATA#
# Given: {"name": "John", "age": 30, "city": "NYC"}
jq '.name' # "John"
jq '.age' # 30
# Given: {"user": {"name": "John", "email": "j@example.com"}}
jq '.user.name' # "John"
jq '.user | .name' # Same, using pipe
# Given: [1, 2, 3, 4, 5]
jq '.[0]' # 1
jq '.[2]' # 3
jq '.[-1]' # 5 (last)
jq '.[1:3]' # [2, 3] (slice)
ARRAY OPERATIONS#
jq '.[]' # Iterate array elements jq '.[0]' # First element jq '.[-1]' # Last element jq '.[2:5]' # Slice [2] to [4] jq '.[:3]' # First 3 elements jq '.[-3:]' # Last 3 elements jq '. | length' # Array length jq '. | reverse' # Reverse array jq '. | sort' # Sort array jq '. | unique' # Unique values jq '. | first' # First element jq '. | last' # Last element jq '. | nth(2)' # Element at index 2 jq 'add' # Sum numbers jq '. + [4,5]' # Append to array jq '. - [2]' # Remove from array
OBJECT OPERATIONS#
jq 'keys' # Get all keys
jq 'values' # Get all values
jq 'keys_unsorted' # Keys in original order
jq 'has("field")' # Check if key exists
jq 'in({"a":1})' # Check if key in object
jq '. | length' # Number of keys
jq 'to_entries' # Convert to [{key, value}]
jq 'from_entries' # Convert back to object
jq 'with_entries(.value += 1)' # Modify all values
MULTIPLE FIELDS#
jq '.field1, .field2' # Multiple fields
jq '{name: .name, age: .age}' # Select and rename
jq '{name, age}' # Shorthand (same names)
jq '[.field1, .field2]' # As array
jq '{a: .x, b: .y}' # Rename fields
FILTERING#
jq '.[] | select(.age > 30)' # Filter by condition
jq '.[] | select(.name == "John")' # Filter by value
jq '.[] | select(.active)' # Filter by boolean
jq '.[] | select(.name | contains("Jo"))' # Contains
jq '.[] | select(.tags[] == "admin")' # Array contains
jq 'map(select(.age > 30))' # Map + select
CONDITIONAL#
jq 'if .age > 30 then "old" else "young" end' jq '.age > 30' # Returns true/false jq '.value // "default"' # Default if null jq '.field? // "missing"' # Suppress errors
TRANSFORMATIONS#
jq 'map(.field)' # Extract field from each
jq 'map(.age + 1)' # Transform each element
jq 'map(select(.active))' # Filter array
jq 'map({name, age})' # Reshape each element
jq '[.[] | .field]' # Collect into array
STRING OPERATIONS#
jq '.name | length' # String length
jq '.name | ascii_downcase' # Lowercase
jq '.name | ascii_upcase' # Uppercase
jq '.name | ltrimstr("Mr. ")' # Remove prefix
jq '.name | rtrimstr(" Jr.")' # Remove suffix
jq '.name | split(" ")' # Split to array
jq '.array | join(", ")' # Join array to string
jq '.name | startswith("J")' # Starts with
jq '.name | endswith("n")' # Ends with
jq '.name | contains("oh")' # Contains
jq '.name | test("^J.*n$")' # Regex test
jq '.name | sub("o"; "0")' # Replace first
jq '.name | gsub("o"; "0")' # Replace all
MATH OPERATIONS#
jq '.value + 10' # Add jq '.value - 5' # Subtract jq '.value * 2' # Multiply jq '.value / 2' # Divide jq '.value % 3' # Modulo jq '.value | floor' # Floor jq '.value | ceil' # Ceiling jq '.value | round' # Round jq '.value | sqrt' # Square root jq '[.values[]] | add' # Sum array jq '[.values[]] | add / length' # Average jq '[.values[]] | min' # Minimum jq '[.values[]] | max' # Maximum
SORTING#
jq 'sort' # Sort array jq 'sort_by(.field)' # Sort by field jq 'sort_by(.age) | reverse' # Sort descending jq 'group_by(.category)' # Group by field jq 'unique_by(.id)' # Unique by field
CONSTRUCTING JSON#
jq -n '{"name": "John"}' # Create from scratch
jq -n '[1,2,3]' # Create array
jq '{name: .first, full: "\(.first) \(.last)"}' # String interpolation
jq '. + {newfield: "value"}' # Add field
jq 'del(.field)' # Delete field
jq '.field = "new"' # Update field
jq '.field |= . + 1' # Update in place
COMBINING DATA#
jq -s '.' # Slurp into array jq -s 'add' # Merge objects jq -s '.[0] * .[1]' # Deep merge jq --slurpfile v vars.json '.' # Load from file
REAL WORLD EXAMPLES#
# Parse AWS CLI output
aws ec2 describe-instances | jq '.Reservations[].Instances[] | {id: .InstanceId, state: .State.Name}'
# Parse kubectl output
kubectl get pods -o json | jq '.items[] | {name: .metadata.name, status: .status.phase}'
# Extract from API response
curl -s api.example.com | jq '.data[] | select(.active) | .name'
# Format log entries
cat log.json | jq -r '"\(.timestamp) [\(.level)] \(.message)"'
# Count by field
jq 'group_by(.status) | map({status: .[0].status, count: length})'
# Get unique values
jq '[.[] | .category] | unique'
# Flatten nested arrays
jq '[.[] | .items[]]'
# Convert CSV-like to JSON
jq -Rs 'split("\n") | map(split(",")) | map({name: .[0], value: .[1]})'
# Update nested value
jq '.users[0].name = "New Name"'
# Remove null values
jq 'walk(if type == "object" then with_entries(select(.value != null)) else . end)'
# Pretty print with color (requires -C)
jq -C '.' file.json | less -R
INPUT OPTIONS#
jq -n 'expression' # No input jq -s 'expression' # Slurp (array from inputs) jq -R 'expression' # Raw input (strings) jq -c 'expression' # Compact output jq -r 'expression' # Raw output (no quotes) jq -j 'expression' # No newline after output jq -e 'expression' # Set exit code on false/null jq -S 'expression' # Sort object keys jq -a 'expression' # ASCII output jq --tab # Use tabs for indentation
ARGUMENTS#
jq --arg name "John" '.name = $name' # String variable jq --argjson num 42 '.count = $num' # JSON variable jq --slurpfile data file.json '. + $data[0]' # Load from file jq --rawfile text file.txt '.content = $text' # Raw file content
ERROR HANDLING#
jq '.missing?' # Suppress errors jq '.missing // "default"' # Default value jq 'try .field catch "error"' # Try/catch jq 'if .field then .field else empty end' # Conditional
DEBUGGING#
jq 'debug' # Print debug info jq '. as $x | debug | $x' # Debug without changing jq 'type' # Show type
QUICK REFERENCE#
jq '.' Pretty print jq '.field' Get field jq '.[0]' First element jq '.[]' All elements jq -r Raw output jq -c Compact jq -s Slurp to array jq 'select()' Filter jq 'map()' Transform jq 'sort_by()' Sort jq 'group_by()' Group jq 'keys' Get keys jq 'length' Count
JQ CHEATSHEET
=============
Source: https://cheatsheet.johlem.net
jq is a lightweight command-line JSON processor.
It's like sed/awk for JSON data.
BASIC USAGE
-----------
jq '.' file.json # Pretty print JSON
cat file.json | jq '.' # Pipe JSON to jq
echo '{"a":1}' | jq '.' # Parse inline JSON
jq -r '.field' file.json # Raw output (no quotes)
jq -c '.' file.json # Compact output
jq -S '.' file.json # Sort keys
BASIC FILTERS
-------------
jq '.' file.json # Identity (pass through)
jq '.field' file.json # Get field value
jq '.field1.field2' file.json # Nested field
jq '.[0]' file.json # First array element
jq '.[-1]' file.json # Last array element
jq '.[]' file.json # All array elements
jq '.field[]' file.json # All elements in field array
ACCESSING DATA
--------------
# Given: {"name": "John", "age": 30, "city": "NYC"}
jq '.name' # "John"
jq '.age' # 30
# Given: {"user": {"name": "John", "email": "j@example.com"}}
jq '.user.name' # "John"
jq '.user | .name' # Same, using pipe
# Given: [1, 2, 3, 4, 5]
jq '.[0]' # 1
jq '.[2]' # 3
jq '.[-1]' # 5 (last)
jq '.[1:3]' # [2, 3] (slice)
ARRAY OPERATIONS
----------------
jq '.[]' # Iterate array elements
jq '.[0]' # First element
jq '.[-1]' # Last element
jq '.[2:5]' # Slice [2] to [4]
jq '.[:3]' # First 3 elements
jq '.[-3:]' # Last 3 elements
jq '. | length' # Array length
jq '. | reverse' # Reverse array
jq '. | sort' # Sort array
jq '. | unique' # Unique values
jq '. | first' # First element
jq '. | last' # Last element
jq '. | nth(2)' # Element at index 2
jq 'add' # Sum numbers
jq '. + [4,5]' # Append to array
jq '. - [2]' # Remove from array
OBJECT OPERATIONS
-----------------
jq 'keys' # Get all keys
jq 'values' # Get all values
jq 'keys_unsorted' # Keys in original order
jq 'has("field")' # Check if key exists
jq 'in({"a":1})' # Check if key in object
jq '. | length' # Number of keys
jq 'to_entries' # Convert to [{key, value}]
jq 'from_entries' # Convert back to object
jq 'with_entries(.value += 1)' # Modify all values
MULTIPLE FIELDS
---------------
jq '.field1, .field2' # Multiple fields
jq '{name: .name, age: .age}' # Select and rename
jq '{name, age}' # Shorthand (same names)
jq '[.field1, .field2]' # As array
jq '{a: .x, b: .y}' # Rename fields
FILTERING
---------
jq '.[] | select(.age > 30)' # Filter by condition
jq '.[] | select(.name == "John")' # Filter by value
jq '.[] | select(.active)' # Filter by boolean
jq '.[] | select(.name | contains("Jo"))' # Contains
jq '.[] | select(.tags[] == "admin")' # Array contains
jq 'map(select(.age > 30))' # Map + select
CONDITIONAL
-----------
jq 'if .age > 30 then "old" else "young" end'
jq '.age > 30' # Returns true/false
jq '.value // "default"' # Default if null
jq '.field? // "missing"' # Suppress errors
TRANSFORMATIONS
---------------
jq 'map(.field)' # Extract field from each
jq 'map(.age + 1)' # Transform each element
jq 'map(select(.active))' # Filter array
jq 'map({name, age})' # Reshape each element
jq '[.[] | .field]' # Collect into array
STRING OPERATIONS
-----------------
jq '.name | length' # String length
jq '.name | ascii_downcase' # Lowercase
jq '.name | ascii_upcase' # Uppercase
jq '.name | ltrimstr("Mr. ")' # Remove prefix
jq '.name | rtrimstr(" Jr.")' # Remove suffix
jq '.name | split(" ")' # Split to array
jq '.array | join(", ")' # Join array to string
jq '.name | startswith("J")' # Starts with
jq '.name | endswith("n")' # Ends with
jq '.name | contains("oh")' # Contains
jq '.name | test("^J.*n$")' # Regex test
jq '.name | sub("o"; "0")' # Replace first
jq '.name | gsub("o"; "0")' # Replace all
MATH OPERATIONS
---------------
jq '.value + 10' # Add
jq '.value - 5' # Subtract
jq '.value * 2' # Multiply
jq '.value / 2' # Divide
jq '.value % 3' # Modulo
jq '.value | floor' # Floor
jq '.value | ceil' # Ceiling
jq '.value | round' # Round
jq '.value | sqrt' # Square root
jq '[.values[]] | add' # Sum array
jq '[.values[]] | add / length' # Average
jq '[.values[]] | min' # Minimum
jq '[.values[]] | max' # Maximum
SORTING
-------
jq 'sort' # Sort array
jq 'sort_by(.field)' # Sort by field
jq 'sort_by(.age) | reverse' # Sort descending
jq 'group_by(.category)' # Group by field
jq 'unique_by(.id)' # Unique by field
CONSTRUCTING JSON
-----------------
jq -n '{"name": "John"}' # Create from scratch
jq -n '[1,2,3]' # Create array
jq '{name: .first, full: "\(.first) \(.last)"}' # String interpolation
jq '. + {newfield: "value"}' # Add field
jq 'del(.field)' # Delete field
jq '.field = "new"' # Update field
jq '.field |= . + 1' # Update in place
COMBINING DATA
--------------
jq -s '.' # Slurp into array
jq -s 'add' # Merge objects
jq -s '.[0] * .[1]' # Deep merge
jq --slurpfile v vars.json '.' # Load from file
REAL WORLD EXAMPLES
-------------------
# Parse AWS CLI output
aws ec2 describe-instances | jq '.Reservations[].Instances[] | {id: .InstanceId, state: .State.Name}'
# Parse kubectl output
kubectl get pods -o json | jq '.items[] | {name: .metadata.name, status: .status.phase}'
# Extract from API response
curl -s api.example.com | jq '.data[] | select(.active) | .name'
# Format log entries
cat log.json | jq -r '"\(.timestamp) [\(.level)] \(.message)"'
# Count by field
jq 'group_by(.status) | map({status: .[0].status, count: length})'
# Get unique values
jq '[.[] | .category] | unique'
# Flatten nested arrays
jq '[.[] | .items[]]'
# Convert CSV-like to JSON
jq -Rs 'split("\n") | map(split(",")) | map({name: .[0], value: .[1]})'
# Update nested value
jq '.users[0].name = "New Name"'
# Remove null values
jq 'walk(if type == "object" then with_entries(select(.value != null)) else . end)'
# Pretty print with color (requires -C)
jq -C '.' file.json | less -R
INPUT OPTIONS
-------------
jq -n 'expression' # No input
jq -s 'expression' # Slurp (array from inputs)
jq -R 'expression' # Raw input (strings)
jq -c 'expression' # Compact output
jq -r 'expression' # Raw output (no quotes)
jq -j 'expression' # No newline after output
jq -e 'expression' # Set exit code on false/null
jq -S 'expression' # Sort object keys
jq -a 'expression' # ASCII output
jq --tab # Use tabs for indentation
ARGUMENTS
---------
jq --arg name "John" '.name = $name' # String variable
jq --argjson num 42 '.count = $num' # JSON variable
jq --slurpfile data file.json '. + $data[0]' # Load from file
jq --rawfile text file.txt '.content = $text' # Raw file content
ERROR HANDLING
--------------
jq '.missing?' # Suppress errors
jq '.missing // "default"' # Default value
jq 'try .field catch "error"' # Try/catch
jq 'if .field then .field else empty end' # Conditional
DEBUGGING
---------
jq 'debug' # Print debug info
jq '. as $x | debug | $x' # Debug without changing
jq 'type' # Show type
QUICK REFERENCE
---------------
jq '.' Pretty print
jq '.field' Get field
jq '.[0]' First element
jq '.[]' All elements
jq -r Raw output
jq -c Compact
jq -s Slurp to array
jq 'select()' Filter
jq 'map()' Transform
jq 'sort_by()' Sort
jq 'group_by()' Group
jq 'keys' Get keys
jq 'length' Count
Defensive reference on CyberRamen. Offensive / red-team sheets live on OffensiveRamen.com.