前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >shell脚本实现格式化JSON字串

shell脚本实现格式化JSON字串

作者头像
PedroQin
发布2020-04-26 22:44:47
3K0
发布2020-04-26 22:44:47
举报
文章被收录于专栏:WriteSimpleDemo

导言

工作中时常要上传json数据,上传前做校对时,单行的一长串json数据不方便校对,复制到 vscode中用插件实现格式化又麻烦,故有了写个脚本工具实现格式化输出json的想法。

Github

https://github.com/pedroqin/shell_script

实现效果

将单行json数据格式化为有缩进层次的多行文本。 示例:

代码语言:javascript
复制
 1apple@Pedro-Mac-mini ~/D/json_tool> ./format_json.sh -f json.txt
 2{
 3  "message" : "success感谢又拍云(upyun.com)提供CDN赞助",
 4  "status" : 200,
 5  "date" : "20200422",
 6  "time" : "2020-04-22 22:22:23",
 7  "cityInfo" : {
 8    "city" : "天津市",
 9    "citykey" : "101030100",
10    "parent" : "天津",
11    "updateTime" : "17:33"
12  },
13  "data" : {
14    "shidu" : "8%",
15    "pm25" : 11.0,
16    "pm10" : 31.0,
17    "quality" : "优",
18    "wendu" : "15",
19    "ganmao" : "各类人群可自由活动",
20    "forecast" : [
21      {
22        "date" : "22",
23        "high" : "高温 16℃",
24        "low" : "低温 6℃",
25        "ymd" : "2020-04-22",
26        "week" : "星期三",
27        "sunrise" : "05:26",
28        "sunset" : "18:55",
29        "aqi" : 37,
30        "fx" : "西北风",
31        "fl" : "4-5级",
32        "type" : "晴",
33        "notice" : "愿你拥有比阳光明媚的心情"
34      }
35    ],
36    "yesterday" : {
37      "date" : "21",
38      "high" : "高温 15℃",
39      "low" : "低温 6℃",
40      "ymd" : "2020-04-21",
41      "week" : "星期二",
42      "sunrise" : "05:28",
43      "sunset" : "18:54",
44      "aqi" : 60,
45      "fx" : "西北风",
46      "fl" : "5-6级",
47      "type" : "晴",
48      "notice" : "愿你拥有比阳光明媚的心情"
49    }
50  }
51}

实现思路

  1. 视整个json数据为一个字串,依次获取每个字符。一般使用的方式有两种如下:
  • 使用read每次获取单个字符,但需注意,使用read时需先设置$IFS(Internal Field Seprator),否则空格会直接跳过,另还有其他一些问题,需要考虑的特殊情况较多,实现稍繁琐。
代码语言:javascript
复制
1ifs_bak="$IFS"
2IFS=$'\n'
3echo "$strings"|while ((1)); do
4    read -s -r -n 1 ch
5    judge_char "$ch"
6    [ -z "$ch" ] && break
7done
8IFS="$ifs_bak"
  • 使用字符串截取,无使用read时的特殊情况,推荐
代码语言:javascript
复制
1offset=0
2while ((1)); do
3    ch="${strings:$offset:1}"
4    judge_char "$ch"
5    [ -z "$ch" ] && break
6    let offset++
7done
  1. 将上一步获取的字符做判断,筛选出六个构造字符(“[”、“]”、“{”、“}”、“:”、“,”),并实现对应缩进长度和换行

其他注意点

  1. 在json 对象和数组中的“[”、“]”、“{”、“}”、“:”、“,” 为普通字符,需加判断,本文处使用flag值做判断
  2. 实现缩进的关键点在于缩进字串长度的控制,以及六个构造字符打印时伴随的换行和缩进字符的打印

代码

代码语言:javascript
复制
  1#!/bin/bash
  2###############################################
  3# Filename    :   format_json.sh
  4# Author      :   PedroQin
  5# Date        :   2020-04-22 18:33:35
  6# Description :   
  7# Version     :   1.0.1
  8###############################################
  9
 10# you can diy indent ,like "\t or "  "
 11indent="  "
 12
 13##############################################
 14indent_num=0
 15indent_str=""
 16double_quotes=false
 17#A string is a sequence of zero or more Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string. A string is very much like a C or Java string. --- by https://www.json.org/json-en.html ,so single quote is not accepted !
 18#single_quote=false
 19# show message in green
 20function green_message()
 21{
 22    echo -ne "\033[32m$@\033[0m"
 23    echo
 24}
 25
 26# show message in red
 27function red_message()
 28{
 29    echo -ne "\033[31m$@\033[0m"
 30    echo
 31}
 32
 33function judge_char()
 34{
 35    case "$1" in
 36        "{")
 37        [ "$double_quotes" == "true" ] && echo -n "$1" && return
 38        let indent_num++
 39        combining_indent +
 40        echo "{"
 41        echo -ne "$indent_str"
 42        ;;
 43
 44        "}")
 45        [ "$double_quotes" == "true" ] && echo -n "$1" && return
 46        let indent_num--
 47        combining_indent -
 48        echo
 49        echo -ne "$indent_str}"
 50        ;;
 51
 52        "[")
 53        [ "$double_quotes" == "true" ] && echo -n "$1" && return
 54        let indent_num++
 55        combining_indent +
 56        echo "["
 57        echo -ne "$indent_str"
 58        ;;
 59
 60        "]")
 61        [ "$double_quotes" == "true" ] && echo -n "$1" && return
 62        let indent_num--
 63        combining_indent -
 64        echo
 65        echo -ne "$indent_str]"
 66        ;;
 67
 68        ",")
 69        [ "$double_quotes" == "true" ] && echo -n "$1" && return
 70        echo ","
 71        echo -ne "$indent_str"
 72        ;;
 73
 74        '"')
 75        [ "$double_quotes" == "true" ] && double_quotes=false || double_quotes=true
 76        echo -n '"'
 77        ;;
 78
 79        ":")
 80        [ "$double_quotes" == "false" ] && echo -n " : " || echo -n ":"
 81        ;;
 82
 83        "\\")
 84        # if get \ ,will skip the next char, mostly it is \n
 85        [ "$double_quotes" == "false" ] && let offset++ || echo -n "\\"
 86        ;;
 87
 88        *)
 89        echo -n "$1"
 90        ;;
 91
 92    esac
 93}
 94
 95function combining_indent()
 96{
 97    if [ $indent_num -lt 0 ];then
 98        red_message "Wrong Json format!"
 99        exit 255
100    fi
101    case $1 in
102        +)
103        indent_str+=$indent
104        ;;
105        -)
106        indent_str=${indent_str%"$indent"}
107        ;;
108
109    esac
110}
111
112function usage()
113{
114    cat << USAGE
115$0 -f \$json_file
116$0 \$json_str
117USAGE
118    exit 255
119}
120
121if [ "$1" == "-f" ] || [ "$1" == "--file"  ];then
122    file_name=$2
123    [ ! -f "$file_name" ] && red_message "Can't find the file :$file_name" && usage
124    strings="$(cat $file_name)"
125else
126    strings="$@"
127fi
128
129offset=0
130while ((1)); do
131    ch="${strings:$offset:1}"
132    judge_char "$ch"
133    [ -z "$ch" ] && break
134    let offset++
135done
136echo

附录

获取天津15天天气JSON数据(http://t.weather.sojson.com/api/weather/city/101030100)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WriteSimpleDemo 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Github
  • 实现效果
  • 实现思路
  • 其他注意点
  • 代码
  • 附录
相关产品与服务
内容分发网络 CDN
内容分发网络(Content Delivery Network,CDN)通过将站点内容发布至遍布全球的海量加速节点,使其用户可就近获取所需内容,避免因网络拥堵、跨运营商、跨地域、跨境等因素带来的网络不稳定、访问延迟高等问题,有效提升下载速度、降低响应时间,提供流畅的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档