在linux bash中使用正则表达式获取json值

在linux bash中使用正则表达式获取json值

我有一个 json 文件文件.json像这样:

{
  "abc": "123",
  "def": 456,
  "ghi": 789
}

我试图在 bash 终端中使用正则表达式获取所有键的值。

这是我尝试获取价值的方法ABC:

var=cat file.json
regex='(abc\":) \"(.+)\",'
[[ $var =~ $regex ]]
echo ${BASE_REMATCH[1]}

它不打印任何东西。我正在尝试获取/打印值ABCIE“123”

请注意,我无法使用 jq,因为它无法在我需要它的机器上使用,而且我也无法安装它。

答案1

你需要类似的东西:

var=$(cat file.json) || exit
regex='"abc"[[:space:]]*:[[:space:]]*"((\\.|[^"\\])*)"'
if [[ $var =~ $regex ]]; then
  value=${BASH_REMATCH[1]}
  printf '%s\n' "$value"
fi

但即便如此,您也需要解码 json 字符串才能获取实际值。例如,foo\"\nbar应转换为foo"<newline>bar和。\u0031\u0032\u0033123

最好是使用合适的 json 解析器:

value=$(jq .abc < file.json)
value=$(PERL_UNICODE= json_xs -t none -e 'print $_->{abc}' < file.json)
value=$(perl -C -MJSON -0777 -ne 'print decode_json($_)->{abc}' file.json)
value=$(
  python3 -c 'import sys, json; print(json.load(sys.stdin)["abc"])' < file.json
)

您的方法存在的问题是:

  • 获取命令输出的语法是 或$(cmd)已弃用的`cmd`.var=cat file.json将尝试运行在其环境中传递的file.json命令。var=cat
  • \"在正则表达式中没有任何意义。它可能被认为是相同的,"但不能保证。
  • .+尽可能多地匹配一个或多个字符,因此它将匹配s 和换行符,直到字符串中的"最后一个。在这里,我们将其替换为零个或多个(而不是)"的序列,后跟任何单个字符或除or之外的字符,因此它会运行到下一个未转义的。*+\\""
  • 您的正则表达式中有两个捕获组,第一个捕获组是 匹配的(abc\":),而您显然需要第二个捕获组(值)。
  • 变量是$BASH_REMATCH, 不是$BASE_REMATCH
  • 您不能用于echo输出任意数据。
  • 至少在列表上下文中,参数扩展必须在 bash 中引用。

答案2

如果您的文件确实像您显示的那样简单(字符串值中没有任何特殊的 JSON 编码),我将只使用awk

$ awk '$1=="\"abc\":"{print $2}' file | tr -d '",'
123

甚至 GNU grep

$ grep -oP '"abc":\s*"?\K[^,]+' file | tr -d '",'
123

启用-PPCRE 正则表达式,让我们\K“忽略到目前为止匹配的所有内容”。使用\K选项-o(“仅打印行的匹配部分”)让我们可以使用某些东西来找到正确的匹配项,然后将其丢弃,以便它不包含在输出中。所以在这里,我们要查找字符串"abc":,然后是 0 个或多个空白字符 ( \s*),后跟 0 个或一个引号 ( "?),我们丢弃到目前为止的所有内容,然后查找最长的非"字符 ( [^"]+)。

最后,tr将删除任何",字符,留下不带引号的值。

相关内容