snippetbashTippending
Shell scripting: parsing command output safely
Viewed 0 times
parsingjqawkcutfield splittingparameter expansion
Problem
Need to extract specific fields from command output in shell scripts without brittle text parsing.
Solution
Safe parsing patterns:
Anti-patterns:
# Use built-in field splitting
# Get specific columns from output
docker ps --format '{{.Names}}\t{{.Status}}' | while IFS=
Anti-patterns:
- Don't parse
ls output (use glob patterns instead) - Don't use regex for JSON/XML (use jq/xmlstarlet)
- Don't use
grep | awk | sed chains when awk alone suffices
\t' read -r name status; do
echo "Container: $name -> $status"
done
# Parse key=value output
while IFS='=' read -r key value; do
case "$key" in
hostname) HOSTNAME="$value" ;;
port) PORT="$value" ;;
esac
done < config.env
# JSON parsing with jq (always prefer for JSON)
curl -s api.example.com/users | jq -r '.[] | "\(.name)\t\(.email)"'
# Get specific JSON field
VERSION=$(jq -r '.version' package.json)
# Conditional with jq
jq -e '.status == "active"' response.json && echo "Active"
# awk for columnar data
df -h | awk 'NR>1 && $5+0 > 80 {print $6, $5}'
# Skip header, find > 80% used partitions
# cut for delimited fields
echo "user:password:1000:1000:User:/home/user:/bin/bash" | cut -d: -f1,3
# Output: user:1000
# Parameter expansion (no external tools needed)
path="/home/user/documents/file.tar.gz"
echo "${path##*/}" # file.tar.gz (basename)
echo "${path%/*}" # /home/user/documents (dirname)
echo "${path%%.*}" # /home/user/documents/file (remove all extensions)
echo "${path%.gz}" # /home/user/documents/file.tar (remove last extension)Anti-patterns:
- Don't parse
lsoutput (use glob patterns instead) - Don't use regex for JSON/XML (use jq/xmlstarlet)
- Don't use
grep | awk | sedchains whenawkalone suffices
Why
Proper field splitting and structured output formats (JSON, TSV) are more reliable than brittle regex on unstructured text.
Context
Shell scripts that process command output
Revisions (0)
No revisions yet.