我试图解析从curl请求返回的JSON,就像这样:

curl 'http://twitter.com/users/username.json' |
    sed -e 's/[{}]/''/g' | 
    awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}'

上面将JSON划分为多个字段,例如:

% ...
"geo_enabled":false
"friends_count":245
"profile_text_color":"000000"
"status":"in_reply_to_screen_name":null
"source":"web"
"truncated":false
"text":"My status"
"favorited":false
% ...

我如何打印一个特定的字段(由-v k=文本表示)?


当前回答

如果安装了Node.js,这对我来说是有效的:

node -pe "require('${HOME}/.config/dev-utils.json').doToken"

其他回答

使用PHP CLI解析JSON

这可以说是跑题了,但是由于优先级的原因,如果不提到我们值得信赖和忠诚的PHP,这个问题仍然是不完整的,对吗?

它使用相同的示例JSON,但让我们将其分配给一个变量以减少模糊性。

export JSON='{"hostname":"test","domainname":"example.com"}'

对于PHP来说,它使用了file_get_contents和PHP://stdin流包装器。

echo $JSON | php -r 'echo json_decode(file_get_contents("php://stdin"))->hostname;'

或者使用fgets和已经在CLI常量STDIN中打开的流。

echo $JSON | php -r 'echo json_decode(fgets(STDIN))->hostname;'

还有一个非常简单但功能强大的JSON CLI处理工具fx。

例子

使用匿名函数:

echo '{"key": "value"}' | fx "x => x.key"

输出:

value

如果你不传递匿名函数参数→…,代码将自动转换为匿名函数。你可以通过这个关键字访问JSON:

$ echo '[1,2,3]' | fx "this.map(x => x * 2)"
[2, 4, 6]

或者也可以使用点语法:

echo '{"items": {"one": 1}}' | fx .items.one

输出:

1

你可以传递任意数量的匿名函数来减少JSON:

echo '{"items": ["one", "two"]}' | fx "this.items" "this[1]"

输出:

two

您可以使用扩展操作符更新现有JSON:

echo '{"count": 0}' | fx "{...this, count: 1}"

输出:

{"count": 1}

只是简单的JavaScript。没有必要学习新的语法。


fx的后期版本有一个互动模式!-

如果有人只想从简单的JSON对象中提取值,而不需要嵌套结构,那么甚至不需要离开Bash就可以使用正则表达式。

下面是我使用基于JSON标准的bash正则表达式定义的函数:

function json_extract() {
  local key=$1
  local json=$2

  local string_regex='"([^"\]|\\.)*"'
  local number_regex='-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?'
  local value_regex="${string_regex}|${number_regex}|true|false|null"
  local pair_regex="\"${key}\"[[:space:]]*:[[:space:]]*(${value_regex})"

  if [[ ${json} =~ ${pair_regex} ]]; then
    echo $(sed 's/^"\|"$//g' <<< "${BASH_REMATCH[1]}")
  else
    return 1
  fi
}

注意:对象和数组不支持作为值,但支持标准中定义的所有其他值类型。另外,只要具有完全相同的键名,无论对在JSON文档中有多深,都将匹配。

以OP为例:

$ json_extract text "$(curl 'http://twitter.com/users/username.json')"
My status

$ json_extract friends_count "$(curl 'http://twitter.com/users/username.json')"
245

Niet是一个工具,可以帮助您直接在shell或Bash CLI中从JSON或YAML文件中提取数据。

pip install niet

考虑一个名为project的JSON文件。Json,包含以下内容:

{
  project: {
    meta: {
      name: project-sample
    }
}

你可以这样使用Niet:

PROJECT_NAME=$(niet project.json project.meta.name)
echo ${PROJECT_NAME}

输出:

project-sample

你可以尝试这样做-

curl -s 'http://twitter.com/users/jaypalsingh.json' | 
awk -F=":" -v RS="," '$1~/"text"/ {print}'