如何通过命令行工具按外层对象名称排序JSON文件?
用命令行工具给JSON外层对象按键名排序的方法
你需要把input.json的外层对象按键名(比如"bar"、"foo")的字母顺序排序,下面给你几种可行的命令行实现方案:
1. 用jq(最省心靠谱的JSON工具)
jq是专门处理JSON的命令行工具,处理这种排序需求简直是小菜一碟。直接用sort_keys过滤器就能一键搞定:
jq --sort-keys . input.json > output.json
要是你只想给外层键排序,不想动内层的结构,可以用更精准的命令:
jq 'to_entries | sort_by(.key) | from_entries' input.json > output.json
这个命令的逻辑很直白:
to_entries:把外层对象转成{"key": "键名", "value": 对应值}的数组sort_by(.key):按数组里的key字段(也就是原JSON的外层键名)排序from_entries:把排序后的数组转回JSON对象
2. 用awk实现(没jq时的备选方案)
如果环境里没装jq,也可以用awk写个脚本处理,但注意这个方法只适合格式特别规整的JSON(比如你示例里这种,外层每个键值对都占多行、缩进一致)。
先把下面的代码存成sort_json.awk文件:
BEGIN { in_obj = 0 current_key = "" current_value = "" } /^{/ { in_obj = 1 print "{" next } /^}/ { in_obj = 0 # 存最后一个键值对 if (current_key != "") { key_value_pairs[current_key] = current_value } # 按键名排序后输出 n = asorti(key_value_pairs, sorted_keys) for (i=1; i<=n; i++) { printf " \"%s\":%s", sorted_keys[i], key_value_pairs[sorted_keys[i]] if (i < n) print "," else print "" } print "}" next } in_obj && /^[[:space:]]*".*":/ { # 先存上一个键值对 if (current_key != "") { key_value_pairs[current_key] = current_value } # 提取当前键名 match($0, /^[[:space:]]*"([^"]+)":/) current_key = substr($0, RSTART+1, RLENGTH-3) # 初始化当前值的内容 current_value = substr($0, RSTART+RLENGTH) "\n" next } in_obj { # 追加值的后续行内容 current_value = current_value $0 "\n" }
然后执行命令:
awk -f sort_json.awk input.json > output.json
要是你的JSON格式变复杂了(比如嵌套多层、键值对挤在同一行),这个脚本大概率会失效,所以还是优先用jq。
关于sed和boost.json的说明
- sed:sed是按行处理文本的工具,JSON是结构化数据,用sed处理很容易因为格式变动出问题,完全不推荐用它来搞JSON结构排序。
- boost.json:它是C的JSON库,本身没有自带命令行工具,但你可以基于它写个简单的C程序,编译成命令行工具用。示例代码大概是这样:
#include <boost/json.hpp> #include <fstream> #include <iostream> #include <map> namespace json = boost::json; int main(int argc, char* argv[]) { if (argc != 3) { std::cerr << "用法: " << argv[0] << " <input.json> <output.json>" << std::endl; return 1; } // 读取输入JSON文件 std::ifstream in_file(argv[1]); json::value json_val = json::parse(in_file); json::object json_obj = json_val.as_object(); // 用map自动按键名排序 std::map<std::string, json::value> sorted_map; for (auto& [key, val] : json_obj) { sorted_map[key] = std::move(val); } // 转回JSON对象并写入输出文件 json::object sorted_obj(sorted_map.begin(), sorted_map.end()); std::ofstream out_file(argv[2]); out_file << json::serialize(sorted_obj); return 0; }
编译的时候要链接boost库,比如:
g++ -o sort_json_boost sort_json_boost.cpp -lboost_json
编译完执行:
./sort_json_boost input.json output.json
内容的提问来源于stack exchange,提问作者Tryer
相关产品推荐
相关产品推荐

