Shell 脚本轻松搞定 JSON 文件写入:实用技巧与示例**
在现代软件开发和运维任务中,JSON(JavaScript Object Notation)因其轻量级、易读易写的特性,已成为数据交换的主流格式之一,Shell 脚本作为 Linux/Unix 环境下强大的自动化工具,经常需要处理 JSON 数据,包括生成和写入 JSON 文件,本文将详细介绍几种在 Shell 中写入 JSON 文件的方法,从简单到复杂,并附上实用示例。
为什么在 Shell 中写入 JSON 文件?
在 Shell 脚本中写入 JSON 文件有多种应用场景,
- 配置文件生成:动态生成应用程序的配置文件。
- 数据导出:将命令行工具或数据库查询结果导出为 JSON 格式。
- API 交互:为 RESTful API 准备请求数据或解析响应数据。
- 日志记录:以结构化 JSON 格式记录日志,便于后续分析和处理。
方法一:直接使用 echo 和重定向(适用于简单 JSON)
对于非常简单的 JSON 结构,可以直接使用 echo 命令结合字符串拼接和重定向来写入文件。
示例:创建一个简单的 JSON 对象
#!/bin/bash
json_file="simple.json"
# 使用 echo 写入简单 JSON
echo '{
"name": "Alice",
"age": 30,
"city": "New York"
}' > "$json_file"
echo "简单 JSON 文件已创建: $json_file"
示例:动态插入变量值
#!/bin/bash
json_file="user.json"
name="Bob"
age=25
city="London"
# 使用双引号和变量插值
echo "{
\"name\": \"$name\",
\"age\": $age,
\"city\": \"$city\"
}" > "$json_file"
echo "带变量的 JSON 文件已创建: $json_file"
注意事项:
- 当变量值中包含双引号 或反斜杠
\等特殊字符时,直接拼接可能会导致 JSON 格式错误或安全漏洞(如注入)。 - 此方法不适用于复杂的、嵌套的 JSON 结构,维护起来非常困难且容易出错。
方法二:使用 printf 格式化(比 echo 更可控)
printf 命令提供了更灵活的格式化输出能力,可以更好地控制 JSON 字符串的格式。
示例:使用 printf 写入 JSON
#!/bin/bash
json_file="formatted.json"
name="Charlie"
age=35
is_active=true
# 使用 printf 格式化,并写入文件
printf '{\n "name": "%s",\n "age": %d,\n "is_active": %s\n}\n' "$name" "$age" "$is_active" > "$json_file"
echo "格式化 JSON 文件已创建: $json_file"
注意事项:
- 同样需要处理变量中的特殊字符。
- 对于复杂结构,拼接字符串依然繁琐。
方法三:使用 jq 工具(推荐,功能强大)
jq 是一个轻量级、灵活的命令行 JSON 处理工具,它能够轻松地创建、修改、查询和格式化 JSON 数据,使用 jq 写入 JSON 文件是最推荐的方法,尤其是处理复杂 JSON 时。
安装 jq
在基于 Debian/Ubuntu 的系统上:
sudo apt-get install jq
在基于 RedHat/CentOS 的系统上:
sudo yum install jq
在 macOS 上(使用 Homebrew):
brew install jq
使用 jq 创建并写入 JSON
示例:创建一个简单的 JSON 对象
#!/bin/bash
json_file="jq_simple.json"
# 使用 jq 的 -n (--null-input) 选项从零开始创建 JSON
jq -n '{
"name": "David",
"age": 40,
"city": "Tokyo"
}' > "$json_file"
echo "使用 jq 创建的简单 JSON 文件: $json_file"
示例:动态插入变量值(推荐方式)
#!/bin/bash
json_file="jq_user.json"
name="Eve"
age=28
city="Paris"
# 使用 --arg 将 Shell 变量传递给 jq
jq -n --arg name "$name" --arg age "$age" --arg city "$city" '{
"name": $name,
"age": ($age | tonumber), # 如果需要数字类型,使用 tonumber
"city": $city
}' > "$json_file"
echo "使用 jq 和变量创建的 JSON 文件: $json_file"
示例:创建复杂的嵌套 JSON 数组
#!/bin/bash
json_file="jq_complex.json"
# 使用 jq 构建复杂的 JSON 结构
jq -n --arg name "Frank" --arg age "45" '{
"user": {
"id": 123,
"username": $name,
"profile": {
"age": ($age | tonumber),
"interests": ["reading", "hiking", "coding"]
},
"is_active": true,
"created_at": "2023-10-27T10:00:00Z"
},
"status": "success"
}' > "$json_file"
echo "使用 jq 创建的复杂 JSON 文件: $json_file"
示例:向现有 JSON 文件添加或修改数据
假设有一个 config.json 文件:
{
"app_name": "MyApp",
"version": "1.0"
}
我们想添加一个 debug 设置:
#!/bin/bash json_file="config.json" # 使用 jq 修改现有 JSON 并写回文件 jq --arg debug_mode "true" '.debug = ($debug_mode | bool)' "$json_file" > temp.json && mv temp.json "$json_file" echo "已更新 JSON 文件: $json_file"
更新后的 config.json:
{
"app_name": "MyApp",
"version": "1.0",
"debug": true
}
方法四:使用 Python(更灵活,适合复杂逻辑)
当 Shell 脚本中的 JSON 处理逻辑非常复杂,或者需要更高级的数据结构操作时,可以调用 Python 脚本来完成。
示例:使用 Python 写入 JSON
#!/bin/bash
json_file="python_json.json"
name="Grace"
age=32
hobbies=["music", "travel", "photography"]
# 使用 Python 的 json 模块
python3 -c "
import json
data = {
'name': '$name',
'age': $age,
'hobbies': $hobbies,
'contact': {
'email': 'grace@example.com'
}
}
with open('$json_file', 'w') as f:
json.dump(data, f, indent=2)
"
echo "使用 Python 创建的 JSON 文件: $json_file"
优点:
- Python 的
json模块非常成熟,功能强大。 - 适合处理极其复杂的 JSON 生成逻辑。
- 可以方便地进行数据计算和转换。
缺点:
- 依赖于 Python 解释器。
- 对于简单的 JSON 操作,略显笨重。
总结与最佳实践
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
echo/重定向 |
简单直接,无需额外工具 | 难以处理复杂结构、特殊字符,易出错 | 非常简单的、静态的 JSON 文件 |
printf |
格式化输出比 echo 灵活 |
仍难以处理复杂结构和特殊字符 | 简单 JSON,需要基本格式控制 |
jq 工具 |
功能强大,易用,处理复杂 JSON 得心应手 | 需要额外安装 jq |
强烈推荐,绝大多数场景 |
| Python 脚本 | 极其灵活,适合复杂逻辑和计算 | 依赖 Python,相对重量级 | JSON 逻辑非常复杂,或需要利用 Python 生态 |
最佳实践建议:
- 优先使用
jq:对于绝大多数 Shell 脚本中处理 JSON 的需求,jq是最佳选择,它专门为 JSON 设计,简洁高效。 - 处理变量:始终使用
jq的--arg(字符串)、--argjson(JSON 对象/数组)等安全的方式将 Shell 变量传递给 JSON,避免手动拼接导致的问题。 - 格式化输出:使用
jq的--indent参数可以生成格式化的 JSON 文



还没有评论,来说两句吧...