如何使 bash shell 脚本用 jq 解析 JSON 文件,然后将结果打印到 PHP 文件?

How to make a bash shell script parse a JSON file with jq and then print results to a PHP file?

我是 bash shell 脚本和自动化的新手。我正在尝试创建一个相对简单的脚本来解析 JSON 文件并从解析的数据中打印一些 PHP。

要解析 JSON 我想使用 jq。这是我的 bash shell 脚本中的代码:

jq . test.json

我 JSON 中的对象具有关于图像的属性。我将从 JSON 使用的属性是:

num = each image is assigned a number, 1 to infinity
filename = the name of the image file
name = the title of the image

示例JSON 文件:

{
   "num": 1,
   "filename": "trees-in-nature.jpg",
   "name": "Trees In Nature"
}
{
   "num": 2,
   "filename": "running-dogs.jpg",
   "name": "Running Dogs"
}
{
   "num": 3,
   "filename": "beautiful-lake.jpg",
   "name": "Beautiful Lake"
}

我想获取已解析的 JSON 属性并将其输出到某些 PHP 代码。 JSON 代码中的每个图像将输出两行 PHP,如下所示(JSON 值显示在星号之间):

if($link == *num*) { $linkURL = "*filename*";}
if($link == *num*) { $altText = "*name*";}

比如我想要输出的最终结果是这样的:

if($link == 1) { $linkURL = "trees-in-nature.jpg";}
if($link == 1) { $altText = "Trees In Nature";}
if($link == 2) { $linkURL = "running-dogs.jpg";}
if($link == 2) { $altText = "Running Dogs";}
...

我坚持的部分是使用 printf 打印上面的 PHP 代码。

一旦我弄清楚并完成 shell 脚本并使其可执行,我想使用此命令将结果打印到 PHP 文件。

./parser.sh > test.php

如何使用 printf 打印出 PHP 并插入 JSON 中的值?

您可以使用 stand-alone jq 脚本直接处理您的 JSON,如下所示:

json2php

#!/usr/bin/env -S jq -sjf

.[] |
(
  # JSON string literal
  "if($link == "

  # Concat with num JSON object member converted to JSON string
  + ( .num | tostring )

  # Concat with JSON string literal
  + ") { $linkURL = \""

  # Concat with filename JSON object member filtered %coded to URI
  + ( .filename | @uri )

  # Concat with JSON string literal including newline
  + "\";}\nif($link == "

  # Concat with num JSON object member converted to JSON string
  + ( .num | tostring )

  # Concat with JSON string literal
  + ") { $altText = \""

  # Concat with name JSON object member filtered to HTML entities if needed
  + ( .name | @html ) + "\";}\n"
)

将文件另存为 json2php 并使其可执行:

chmod +x json2php

用作:

./json2php input.json >test.php

工作原理:

shebang #!/usr/bin/env -S jq -sjf 告诉我们用 -sjf 个参数执行 jq 解释器:

jq 个参数:

  • -s:将输入处理为 JSON 个对象的流,而不是单个 JSON 个对象。
  • -j:生成没有换行符的原始输出。
  • -f:将此作为脚本加载(适用于 shebang)。

现在 jq 脚本本身:

  • .[] |: 管道输入流数组中的每个对象进行处理
  • ( ... ): 分组说明。
  • "if($link == ": 只是要打印的 JSON 字符串文字 as-is (没有双引号 " 因为 jq 已被指示生成使用 -j 选项开关的原始输出。
  • + ( .num | tostring ):与转换为字符串的num成员连接,因此可以将其添加到前一个字符串中。
  • + ") { $linkURL = \"":与另一个 JSON 字符串文字连接。
  • + ( .filename | @uri ):与过滤为 URI 的 filename 成员连接,因此像空格 + & ... 这样的特殊字符将被 % 编码。
  • + "\";}\n":与另一个 JSON 字符串文字连接,包括换行符转义为 \n 以作为原始换行符打印

示例 input.json(注意空格和引号以探测过滤器是否按预期工作):

{
   "num": 1,
   "filename": "trees-in-nature.jpg",
   "name": "Trees In Nature"
}
{
   "num": 2,
   "filename": "running dogs.jpg",
   "name": "Running \"Dogs\""
}
{
   "num": 3,
   "filename": "beautiful-lake.jpg",
   "name": "Beautiful' Lake"
}

根据以上输入生成 php 代码:

if($link == 1) { $linkURL = "trees-in-nature.jpg";}
if($link == 1) { $altText = "Trees In Nature";}
if($link == 2) { $linkURL = "running%20dogs.jpg";}
if($link == 2) { $altText = "Running "Dogs"";}
if($link == 3) { $linkURL = "beautiful-lake.jpg";}
if($link == 3) { $altText = "Beautiful' Lake";}

生成 PHP switch 语句的替代方法:

#!/usr/bin/env -S jq -srf

# JSON string literal
"switch ($link) {",
(
  .[] |
  (
    # JSON string literal
    "    case "

    # Concat with num JSON object member converted to JSON string
    + ( .num | tostring )

    # Concat with JSON string literal
    + ":",

    # New JSON string litteral
    "        $linkURL = \""

    # Concat with filename JSON object member filtered %coded to URI
    + ( .filename | @uri )

    # Concat with JSON string literal
    + "\";",

    # New JSON string litteral
    "        $altText = \""

    # Concat with name JSON object member filtered to HTML entities if needed
    + ( .name | @html )

    # Concat with JSON string literal
    + "\";",

    # New JSON string litteral
    "        break;"
  )
),
# JSON string literal
"}"

来自相同 input.json 的结果:

switch ($link) {
    case 1:
        $linkURL = "trees-in-nature.jpg";
        $altText = "Trees In Nature";
        break;
    case 2:
        $linkURL = "running%20dogs.jpg";
        $altText = "Running "Dogs"";
        break;
    case 3:
        $linkURL = "beautiful-lake.jpg";
        $altText = "Beautiful' Lake";
        break;
}