用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/vamseeachanta/workspace-hub --skill json-config-loader命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Write outbound email and external messages in Vamsee Achanta's voice — a subtle offer to help, never bold or rash claims. Load before drafting ANY email, LinkedIn/Collide reply, proposal note, or outreach sent under his name.
Save/publish analysis or computation results from ANY ecosystem repo to Hugging Face as a queryable, viewer-renderable dataset. Use when the user wants to "save results to hugging face", "publish dataset to HF", "hugging face data saving", "save analysis results", "hf dataset", "make results queryable", or "render via datasets-server API". Reshapes nested results into flat parquet tables, writes a dataset card with a viewer `configs:` block and provenance, applies license/public-vs-private routing, enforces a domain data-quality gate (faithful-to-source != correct), publishes to `aceengineer/<repo>-<projection>`, and verifies via the datasets-server API.
Clone, create, fork, configure, and manage GitHub repositories. Manage remotes, secrets, releases, and workflows. Works with gh CLI or falls back to git + GitHub REST API via curl.
基于 SOC 职业分类
正在显示 SKILL.md
| name | json-config-loader |
| version | 1.0.0 |
| description | Configuration file parsing patterns for bash scripts (INI, key=value, JSON) |
| author | workspace-hub |
| category | bash |
| tags | ["bash","config","json","yaml","parsing","jq","configuration"] |
| platforms | ["linux","macos"] |
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.
✅ Use when:
❌ Avoid when:
Parse simple key=value configuration files:
#!/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=
value=
value=
[[ =~ ^\"(.*)\"$ ]] || [[ =~ ^\'(.*)\'$ ]];
value=
CONFIG[]=
<
}
() {
key=
default=
}
() {
key=
[[ -v CONFIG[] ]]
}
parse_config
has_config ;
Load and manipulate JSON configuration:
#!/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=
default=
value
value=$( | jq -r 2>/dev/null)
[[ -z || == ]];
}
() {
json=
path=
| jq -r 2>/dev/null
}
() {
json=
path=
result
result=$( | jq -e 2>/dev/null)
[[ == ]]
}
check_jq
CONFIG_JSON=$(load_json_config )
DB_HOST=$(json_get )
DB_PORT=$(json_get )
DEBUG=$(json_get )
IFS= -r feature;
< <(json_get_array )
Generate structured JSON reports:
#!/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 \
--argjson errors \
--argjson warnings \
}
() {
report=
items=()
items_json=
item ;
items_json=$( | jq --arg i )
| jq --argjson items
}
() {
report=
file=
-p
| jq >
}
report=$(generate_report 100 5 10)
report=$(add_report_items )
save_report
Parse INI-style files with sections:
#!/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" =~ ^([^=]+)=(.*)$ ]];
key=
value=
key=
key=
value=
value=
INI_CONFIG[]=
<
}
() {
section=
key=
default=
}
() {
section=
prefix=
key ;
[[ == * ]];
}
() {
| -u
}
parse_ini
DB_HOST=$(ini_get )
DB_PORT=$(ini_get )
LOG_LEVEL=$(ini_get )
key $(ini_section_keys );
Load configuration with environment variable overrides:
#!/bin/bash
# ABOUTME: Configuration with environment variable overrides
# ABOUTME: File config < Environment variable precedence
declare -A APP_CONFIG
# Load config with env override support
load_config_with_env() {
local file="$1"
local prefix="${2:-APP_}" # Environment variable prefix
# First load from file
if [[ -f "$file" ]]; then
while IFS= read -r line || [[ -n "$line" ]]; do
[[ "$line" =~ ^[[:space:]]*# ]] && continue
[[ -z "${line// /}" ]] && continue
if [[ "$line" =~ ^([^=]+)=(.*)$ ]]; then
local key="${BASH_REMATCH[1]}"
local value="${BASH_REMATCH[2]}"
key="${key#"${key%%[![:space:]]*}"}"
key="${key%"${key##*[![:space:]]}"}"
APP_CONFIG["$key"]="$value"
<
key ;
env_key=
env_key=
[[ -v ]];
APP_CONFIG[]=
}
() {
missing=()
key ;
[[ -z ]];
missing+=()
[[ -gt 0 ]];
>&2
>&2
1
0
}
() {
key=
default=
}
() {
key=
default=
value=
[[ =~ ^-?[0-9]+$ ]];
}
() {
key=
default=
value=
||1|on) ;;
|no|0|off) ;;
*) ;;
}
load_config_with_env
require_config || 1
PORT=$(config_int 8080)
DEBUG=$(config_bool )
API_KEY=$(config_string )
Parse YAML files when yq is available:
#!/bin/bash
# ABOUTME: YAML configuration parsing with yq
# ABOUTME: Falls back to jq for JSON subset of YAML
# Check for yaml parser
get_yaml_parser() {
if command -v yq &> /dev/null; then
echo "yq"
elif command -v jq &> /dev/null; then
echo "jq" # Can parse YAML's JSON subset
else
echo "none"
fi
}
# Load YAML config
load_yaml_config() {
local file="$1"
local parser
parser=$(get_yaml_parser)
if [[ ! -f "$file" ]]; then
echo "{}"
return 1
fi
case "$parser" in
yq)
yq -o=json "$file" 2>/dev/null || echo "{}"
;;
jq)
# Try to parse as JSON (YAML subset)
jq '.' "$file" 2>/dev/null || echo "{}"
;;
*)
>&2
1
;;
}
() {
file=
path=
default=
parser
parser=$(get_yaml_parser)
value
yq)
value=$(yq -r 2>/dev/null)
;;
jq)
value=$(jq -r 2>/dev/null)
;;
*)
value=
;;
[[ -z || == ]];
}
CONFIG_FILE=
CONFIG_JSON=$(load_yaml_config )
DB_HOST=$(yaml_get )
DB_PORT=$(yaml_get )
Full configuration management with multiple formats:
#!/bin/bash
# ABOUTME: Universal configuration manager
# ABOUTME: Supports key=value, JSON, and environment overrides
set -e
# ─────────────────────────────────────────────────────────────────
# Configuration Storage
# ─────────────────────────────────────────────────────────────────
declare -A CONFIG
CONFIG_FILE=""
CONFIG_FORMAT=""
# ─────────────────────────────────────────────────────────────────
# Format Detection
# ─────────────────────────────────────────────────────────────────
detect_format() {
local file="$1"
case "${file##*.}" in
json) echo "json" ;;
yaml|yml) echo "yaml" ;;
ini) echo "ini" ;;
*) echo "keyvalue" ;;
esac
}
# ─────────────────────────────────────────────────────────────────
# Loaders
# ─────────────────────────────────────────────────────────────────
load_keyvalue() {
local file="$1"
while IFS= read -r line || [[ -n "$line" ]]; do
[[ "$line" =~ ^[[:space:]]*# ]] &&
[[ -z ]] &&
[[ =~ ^([^=]+)=(.*)$ ]];
key=
value=
value=
CONFIG[]=
<
}
() {
file=
! -v jq &> /dev/null;
>&2
1
IFS= -r key value;
CONFIG[]=
< <(jq -r 2>/dev/null)
}
() {
file=
env_prefix=
[[ ! -f ]];
>&2
1
CONFIG=()
CONFIG_FILE=
CONFIG_FORMAT=$(detect_format )
json) load_json ;;
*) load_keyvalue ;;
[[ -n ]];
key ;
env_key=
env_key=
env_key=
[[ -v ]];
CONFIG[]=
}
() {
key=
default=
}
() {
key=
value=
CONFIG[]=
}
() {
[[ -v CONFIG[] ]]
}
() {
|
}
() {
key $(config_keys);
}
() {
json=
key ;
json=$( | jq --arg k --arg v )
| jq
}
() {
missing=()
key ;
! config_has || [[ -z ]];
missing+=()
[[ -gt 0 ]];
>&2
>&2
1
}
() {
key=
value
value=$(config_get )
[[ -n && ! =~ ^-?[0-9]+$ ]];
>&2
1
}
() {
key=
value
value=$(config_get )
[[ -n && ! =~ ^https?:// ]];
>&2
1
}
[[ == ]];
config_load
config_require || 1
config_validate_int || 1
config_validate_url || 1
config_dump
value=$(config_get "key" "default_value")
config_require "api_key" "database_url" || exit 1
# Don't store secrets in files
API_KEY="${API_KEY:-$(config_get 'api_key')}"
if ! jq empty "$file" 2>/dev/null; then
echo "Invalid JSON" >&2
exit 1
fi
if [[ -f "$config_file" ]]; then
load_config "$config_file"
else
echo "Warning: Config not found, using defaults" >&2
fi