

使用 Bash Shell 处理 JSON 文件
source link: https://wsgzao.github.io/post/bash-json/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。本文提供一个真实的测试用例需求,设计逻辑类似 Makefile
,我以 Bash 处理 JSON 为例,Coding 水平有限,请各位多多包涵哈,欢迎大家一起学习和挑战各种不同的语言来实现。
巧用 jq 处理 JSON 数据
2015 年 06 月 19 日 - 初稿
阅读原文 - https://wsgzao.github.io/post/bash-json/
Test Case
In data pipeline system and configuration management systems, it’s very common that you need execute a bunch of jobs which has dependencies with each other.
Write a program pipeline_runner
to execute a list of shell scripts. The definition of those scripts and their dependencies are described in a JSON file. The program only takes in one argument which is the file path of JSON file that defines the jobs.
For example,
// jobs.json
{
"log0_compressed" : {
"commands": "curl http://websrv0/logs/access.log.gz > access0.log.gz",
"input": [],
"output": "access0.log.gz"
},
"log0" : {
"commands": "gunzip access0.log.gz",
"input": ["access0.log.gz"],
"output": "access0.log"
},
"log1_compressed": {
"commands": "curl http://websrv1/logs/access.log.gz > access1.log.gz",
"input": [],
"output": "access1.log.gz"
},
"log1" : {
"commands": "gunzip access1.log.gz",
"input": ["access1.log.gz"],
"output": "access1.log"
},
"log_combined": {
"commands": "cat access0.log access1.log > access.log",
"input": ["access0.log", "access1.log"],
"output": "access.log"
}
}
To run the program
pipeline_runner jobs.json
As you can see, each job has its input files and output files.
- A job will only be executed if all its input files exist.
- A job can have multiple input files (or none) but only produce one output file.
- Users could run the program multiple times, but if a job’s output file already exists, the program would skip the job.
If you’re still not very clear, think of Makefile
in Linux systems. The logic is quite similar.
You could complete the test with the programming language you preferred.
Bash Shell
#!/bin/bash
# dos2unix *.sh
# Program:
# This program to test json.
# History:
# 2015/06/18 by OX
#---------------------------- custom variables ---------------------start
runuser=root
# commands
log_combined_commands=`cat jobs.json | ./jq -r '.log_combined.commands'`
log1_commands=`cat jobs.json | ./jq -r '.log1.commands'`
log1_compressed_commands=`cat jobs.json | ./jq -r '.log1_compressed.commands'`
log0_commands=`cat jobs.json | ./jq -r '.log0.commands'`
log0_compressed_commands=`cat jobs.json | ./jq -r '.log0_compressed.commands'`
# input file name
log0_input=`cat jobs.json | ./jq -r '.log0.input[0]'`
log1_input=`cat jobs.json | ./jq -r '.log1.input[0]'`
log_combined_input1=`cat jobs.json | ./jq -r '.log_combined.input[0]'`
log_combined_input2=`cat jobs.json | ./jq -r '.log_combined.input[1]'`
# output file name
log_combined_output=`cat jobs.json | ./jq -r '.log_combined.output'`
log1_output=`cat jobs.json | ./jq -r '.log1.output'`
log1_compressed_output=`cat jobs.json | ./jq -r '.log1_compressed.output'`
log0_output=`cat jobs.json | ./jq -r '.log0.output'`
log0_compressed_output=`cat jobs.json | ./jq -r '.log0_compressed.output'`
#---------------------------- custom variables ---------------------end
#---------------------------- user check ---------------------start
if [ "`whoami`" != "$runuser" ]; then
echo "Please re-run ${this_file} as $runuser."
exit 1
fi
#---------------------------- user check ---------------------end
#---------------------------- function ---------------------start
pause()
{
read -n1 -p "Press any key to continue..."
}
log_combined_check_first()
{
if [ -f "$log_combined_output" ]; then
echo "${log_combined_output} has been generated, the programe will exit"
exit 0
fi
}
log0_compressed_check()
{
if [ ! -f "$log0_compressed_output" ]; then
eval ${log0_compressed_commands}
fi
}
log0_check()
{
if [ ! -f "$log0_output" ]; then
eval ${log0_commands}
fi
}
log1_compressed_check()
{
if [ ! -f "$log1_compressed_output" ]; then
eval ${log1_compressed_commands}
fi
}
log1_check()
{
if [ ! -f "$log1_output" ]; then
eval ${log1_commands}
fi
}
log_combined_check()
{
if [ ! -f "$log_combined_output" ]; then
eval ${log_combined_commands}
echo "${log_combined_output} has been generated, the programe will exit"
fi
}
#---------------------------- function ---------------------end
#---------------------------- main ---------------------start
echo "
Please read first:
[0]Check jobs.json and jq by yourself first
[1]A job will only be executed if all its input files exist.
[2]A job can have multiple input files (or none) but only produce one output file.
[3]Users could run the program multiple times, but if a job's output file already exists, the program would skip the job.
"
pause
#check if file exist and do the job
log_combined_check_first
log0_compressed_check
log0_check
log1_compressed_check
log1_check
log_combined_check
#---------------------------- main ---------------------end
我的代码未实现任意数量 jobs 的 input,希望大牛指点
file://D:\pipeline (2 folders, 4 files, 490.55 KB, 531.04 KB in total.)
│ jobs.json 794 bytes
│ jq 486.13 KB
│ pipeline_runner 2.95 KB
│ README.md 714 bytes
├─logs (0 folders, 2 files, 248 bytes, 248 bytes in total.)
│ access0.log.gz 123 bytes
│ access1.log.gz 125 bytes
└─result (0 folders, 5 files, 40.25 KB, 40.25 KB in total.)
access.log 20.00 KB
access0.log 10.00 KB
access0.log.gz 123 bytes
access1.log 10.00 KB
access1.log.gz 125 bytes
Recommend
-
169
reddit: the front page of the internet
-
13
Useful Linux Bash Shell Aliases Submitted by NanoDano on Sun, 11/11/2012 - 19:59...
-
20
Send mail with a BASH Shell Script Posted: 2007-06-10 - Last updated: 2019-06-05 Tagged
-
8
当需要大量改变文件扩展名的时候会非常有用,这情况可能很少遇到。但是在调试测试的时候就非常有用。在本文我们将说明如何使用bash的find参数-exec,mv,rename命令递归改变文件的扩展名。-exec顾名思义就是要执行命令的意思。使用find -exec与m...
-
9
Unpacking Bash shell tips from a GitHub Actions workflow Apr 28, 2021 Someone shared a GitHub Actions workflow step which was written to find out some pull request info, but I thought even the first...
-
5
From the bash command shell, parse the numbers of a line advertisements I have a log line that I am pulling from bash like: The...
-
11
「Shell」- 处理 YAML 文件 ...
-
8
Windows 10 的周年更新为开发人员提...
-
10
使用 Bash 脚本语言进行编程时,有时需要创建一个临时文件。例如,你可能需要一个可以提交到磁盘的中间文件,...
-
14
SPL: 专门处理开放格式文件 (txt/csv/json/xml/xls)的Java库...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK