Claude
Skills
Sign in
Back

json-config-loader

Included with Lifetime
$97 forever

Configuration file parsing patterns for bash scripts (INI, key=value, JSON)

bashbashconfigjsonyamlparsingjqconfiguration

What this skill does


# JSON & Config Loader

Patterns for loading, parsing, and generating configuration files in bash scripts. Supports key=value files, JSON with jq, and associative array management. Extracted from workspace-hub's configuration scripts.

## When to Use This Skill

✅ **Use when:**
- Loading configuration from files into bash scripts
- Parsing key=value or INI-style configuration files
- Working with JSON data using jq
- Generating JSON reports from bash
- Managing configuration with associative arrays

❌ **Avoid when:**
- Complex nested configuration (consider Python instead)
- Real-time configuration changes (use a daemon)
- Configuration with complex validation rules

## Core Capabilities

### 1. Key=Value Configuration Parsing

Parse simple key=value configuration files:

```bash
#!/bin/bash
# ABOUTME: Parse key=value configuration files
# ABOUTME: Supports comments, empty lines, and quoted values

CONFIG_FILE="${1:-config.conf}"

# Declare associative array for config
declare -A CONFIG

# Parse configuration file
parse_config() {
    local file="$1"

    if [[ ! -f "$file" ]]; then
        echo "Error: Config file not found: $file" >&2
        return 1
    fi

    while IFS= read -r line || [[ -n "$line" ]]; do
        # Skip comments and empty lines
        [[ "$line" =~ ^[[:space:]]*# ]] && continue
        [[ -z "${line// /}" ]] && continue

        # Parse key=value pairs
        if [[ "$line" =~ ^([^=]+)=(.*)$ ]]; then
            local key="${BASH_REMATCH[1]}"
            local value="${BASH_REMATCH[2]}"

            # Trim whitespace
            key="${key#"${key%%[![:space:]]*}"}"
            key="${key%"${key##*[![:space:]]}"}"
            value="${value#"${value%%[![:space:]]*}"}"
            value="${value%"${value##*[![:space:]]}"}"

            # Remove surrounding quotes if present
            if [[ "$value" =~ ^\"(.*)\"$ ]] || [[ "$value" =~ ^\'(.*)\'$ ]]; then
                value="${BASH_REMATCH[1]}"
            fi

            CONFIG["$key"]="$value"
        fi
    done < "$file"
}

# Get config value with default
get_config() {
    local key="$1"
    local default="${2:-}"

    echo "${CONFIG[$key]:-$default}"
}

# Check if key exists
has_config() {
    local key="$1"
    [[ -v CONFIG[$key] ]]
}

# Usage
parse_config "$CONFIG_FILE"

# Access values
echo "Database: $(get_config 'database' 'default.db')"
echo "Port: $(get_config 'port' '8080')"

if has_config 'debug'; then
    echo "Debug mode enabled"
fi
```

### 2. JSON Configuration with jq

Load and manipulate JSON configuration:

```bash
#!/bin/bash
# ABOUTME: JSON configuration loading with jq
# ABOUTME: Provides safe defaults and nested value access

# Check jq dependency
check_jq() {
    if ! command -v jq &> /dev/null; then
        echo "Error: jq is required but not installed" >&2
        echo "Install with: apt install jq (Ubuntu) or brew install jq (Mac)" >&2
        exit 1
    fi
}

# Load JSON config file
load_json_config() {
    local file="$1"

    if [[ ! -f "$file" ]]; then
        echo "{}"
        return 1
    fi

    # Validate JSON
    if ! jq empty "$file" 2>/dev/null; then
        echo "Error: Invalid JSON in $file" >&2
        echo "{}"
        return 1
    fi

    cat "$file"
}

# Get value from JSON with default
json_get() {
    local json="$1"
    local path="$2"
    local default="${3:-}"

    local value
    value=$(echo "$json" | jq -r "$path // empty" 2>/dev/null)

    if [[ -z "$value" || "$value" == "null" ]]; then
        echo "$default"
    else
        echo "$value"
    fi
}

# Get array from JSON
json_get_array() {
    local json="$1"
    local path="$2"

    echo "$json" | jq -r "$path[]? // empty" 2>/dev/null
}

# Check if path exists in JSON
json_has() {
    local json="$1"
    local path="$2"

    local result
    result=$(echo "$json" | jq -e "$path != null" 2>/dev/null)
    [[ "$result" == "true" ]]
}

# Usage example
check_jq

CONFIG_JSON=$(load_json_config "config.json")

# Access nested values
DB_HOST=$(json_get "$CONFIG_JSON" '.database.host' 'localhost')
DB_PORT=$(json_get "$CONFIG_JSON" '.database.port' '5432')
DEBUG=$(json_get "$CONFIG_JSON" '.settings.debug' 'false')

echo "Database: $DB_HOST:$DB_PORT"
echo "Debug: $DEBUG"

# Iterate array values
echo "Enabled features:"
while IFS= read -r feature; do
    echo "  - $feature"
done < <(json_get_array "$CONFIG_JSON" '.features')
```

### 3. JSON Report Generation

Generate structured JSON reports:

```bash
#!/bin/bash
# ABOUTME: Generate JSON reports from bash data
# ABOUTME: Uses jq for proper JSON encoding and structure

# Generate simple JSON object
generate_json_object() {
    local -n data=$1  # Nameref to associative array

    local json="{}"

    for key in "${!data[@]}"; do
        local value="${data[$key]}"
        json=$(echo "$json" | jq --arg k "$key" --arg v "$value" '. + {($k): $v}')
    done

    echo "$json"
}

# Generate JSON report with structure
generate_report() {
    local status="$1"
    local total="$2"
    local errors="$3"
    local warnings="$4"

    jq -n \
        --arg status "$status" \
        --arg timestamp "$(date -Iseconds)" \
        --arg run_id "$(date +%Y%m%d-%H%M%S)" \
        --argjson total "$total" \
        --argjson errors "$errors" \
        --argjson warnings "$warnings" \
        '{
            metadata: {
                status: $status,
                timestamp: $timestamp,
                run_id: $run_id
            },
            summary: {
                total_processed: $total,
                errors: $errors,
                warnings: $warnings,
                success_rate: (if $total > 0 then (($total - $errors) * 100 / $total) else 0 end)
            }
        }'
}

# Add items to JSON report
add_report_items() {
    local report="$1"
    shift
    local items=("$@")

    # Convert items array to JSON array
    local items_json="[]"
    for item in "${items[@]}"; do
        items_json=$(echo "$items_json" | jq --arg i "$item" '. + [$i]')
    done

    echo "$report" | jq --argjson items "$items_json" '. + {items: $items}'
}

# Save report to file
save_report() {
    local report="$1"
    local file="$2"

    mkdir -p "$(dirname "$file")"
    echo "$report" | jq '.' > "$file"

    echo "Report saved: $file"
}

# Usage
report=$(generate_report "success" 100 5 10)
report=$(add_report_items "$report" "item1" "item2" "item3")
save_report "$report" "reports/analysis-$(date +%Y%m%d).json"
```

### 4. Multi-Section INI Parsing

Parse INI-style files with sections:

```bash
#!/bin/bash
# ABOUTME: Parse INI-style configuration with sections
# ABOUTME: Supports [section] headers and section.key access

declare -A INI_CONFIG
declare -a INI_SECTIONS=()

parse_ini() {
    local file="$1"
    local current_section="default"

    if [[ ! -f "$file" ]]; then
        echo "Error: INI file not found: $file" >&2
        return 1
    fi

    INI_SECTIONS=("default")

    while IFS= read -r line || [[ -n "$line" ]]; do
        # Skip comments and empty lines
        [[ "$line" =~ ^[[:space:]]*[#\;] ]] && continue
        [[ -z "${line// /}" ]] && continue

        # Section header
        if [[ "$line" =~ ^\[([^\]]+)\] ]]; then
            current_section="${BASH_REMATCH[1]}"
            INI_SECTIONS+=("$current_section")
            continue
        fi

        # Key=value within section
        if [[ "$line" =~ ^([^=]+)=(.*)$ ]]; then
            local key="${BASH_REMATCH[1]}"
            local value="${BASH_REMATCH[2]}"

            # Trim whitespace
            key="${key#"${key%%[![:space:]]*}"}"
            key="${key%"${key##*[![:space:]]}"}"
            value="${value#"${value%%[![:space:]]*}"}"
            value="${value%"${value##*[![:space:]]}"}"

            # Store as section.key
            INI_CONFIG["${current_section}.${key}"]="$value"
        fi
    done < "$file"
}

# Get INI value
ini_get() {
    local section="$1"
    local key="$2"
    local default="${3:-}"

    echo "${INI_CONFIG["${section}.${key}"]:-$default}"
}

# 

Related in bash