如何从 json 文件中提取字符串并放入变量(Linux)

如何从 json 文件中提取字符串并放入变量(Linux)

我的一个 json 文件 file1.json 中有以下内容:-

{
  "$quer": {
    "args": [{
      "args": [
        "select\n      db1.table1 as tab1,\n      db1.table2 as tab2,\n      db1.table3 as tab3\n      from db1.table4 as tab4"
      ],
      "fn": "from-sql",
      "ns": "op"
    }],
    "fn": "operators",
    "ns": "op"
  }
}

我想从这个 json 文件中提取字符串db1.table4并存储到变量中。

我不太了解 sed 和 awk。有人能帮忙吗?

答案1

看一看jq命令行 JSON 处理器,例如使用以下命令安装:

sudo apt install jq

你想要的字符串不是 JSON 值,而是 JSON 值的一部分。因此我建议你使用jq将你需要操作的字符串放入变量中,例如:

my_var=$(jq -r .[$quer].args[0].args[0] file1.json)

这将获得一个包含 SELECT 语句的变量:

select db1.table1 as tab1, db1.table2 as tab2, db1.table3 as tab3 from db1.table4 as tab4

然后,您将需要使用其他工具(如 sed、awk、cut 等)从该变量中获取所需的子字符串。对于您的特定情况,这种方法可行,但对于其他 SELECT 语句,这种方法可能行不通。按空格分隔符剪切并返回第 12 个值:

my_table=$(echo $my_var | cut -d' ' -f12)

答案2

  1. 假设您要提取的字符串在每个可以使用的文件中都位于相同的位置headtail并且cut使用管道命令。

  2. 例如:

    $ head -6 file.json | tail -1 | cut -b 121-129
    db1.table
    
  3. 下面是将输出设置为变量的脚本示例:

    #!/bin/bash
    v1=$(head -6 file.json | tail -1 | cut -b 121-130)
    echo "$v1"
    

脚本的输出将是变量db1.table4的值V1

您可以在这里阅读有关这些命令的更多信息:

当然,您可以使用这些命令从文件中提取任何其他字符串。

答案3

通常,应避免使用通用文本解析工具来解析结构化数据。由于您有一个 json 文件,因此使用专用的 json 解析器更安全、更简单。在您的例子中,您可能希望提取数组的第一个元素的值args,该元素本身是顶级数组的第一个元素args,即顶级哈希的子元素$quer

$ jq '."$quer"."args"[0]["args"]' file.json
[
  "select\n      db1.table1 as tab1,\n      db1.table2 as tab2,\n      db1.table3 as tab3\n      from db1.table4 as tab4"
]

从这里开始,您不再拥有结构化数据,您需要采用更粗暴的方法。我不知道您想如何识别目标字符串,您没有解释这一点。因此,根据您实际想要的内容,您可以执行以下操作:

  1. 跳过以[或开头的行],然后打印剩余行的第二个单词:

    $ jq '."$quer"."args"[0]["args"]' file.json | awk '/^[^][]/{print $2}'
    db1.table1
    
  2. 打印第二行的第二个单词

    $ jq '."$quer"."args"[0]["args"]' file.json | awk 'NR==2{print $2}'
    db1.table1
    
  3. 打印字符串后最长的非空白部分"select\n

    $ jq '."$quer"."args"[0]["args"]' file.json | grep -oP '"select\\n\s*\K\S*'
    db1.table1
    

如果您准确解释我们应该如何知道要提取什么字符串,我可以给您一个更有针对性的答案。


为了完成,在你的具体的例如,我强调这不是可移植的,并且如果您的输入数据以任何方式发生变化,几乎肯定会失败,您可以直接使用简单的文本工具:

$ grep -oP '"select\\n\s*\K\S*' file.json 
db1.table1

$ awk '$1=="\"select\\n"{print $2}' file.json 
db1.table1

$ sed -nE 's/.*"select\\n\s*(\S+).*/\1/p' file.json 
db1.table1

相关内容