1

I am brand new to bash shell scripting and automation. I am trying to create a relatively simple script which parses a JSON file and prints some PHP from the data that was parsed.

To parse the JSON I would like to use jq. This is the code in my bash shell script that does that:

jq . test.json

The objects in my JSON have properties about images. The properties I will be using from the JSON are:

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

The example JSON file:

{
   "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"
}

I want to take the parsed JSON properties and output it to some PHP code. Each image in the JSON code will output two lines of PHP that look like this (JSON values are shown between asterisks):

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

For example, the final result I want outputted would look like this:

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";}
...

The part I am stuck on is using printf to print the PHP code above.

Once I figure out that and finalize the shell script and make it executable, I would like to use this command to print the result to a PHP file.

./parser.sh > test.php

How can I use printf to print out the PHP and insert the values from the JSON?

0

1 Answer 1

5

You can process your JSON directly with a stand-alone jq script as follow:

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"
)

Save file as json2php and make it executable:

chmod +x json2php

Use it as:

./json2php input.json >test.php

How it works:

The shebang #!/usr/bin/env -S jq -sjf tells to execute the jq interpreter with -sjf arguments:

jq arguments:

  • -s: Handle the input as a stream of JSON objects rather than as a single JSON object.
  • -j: Produces a raw output without newlines.
  • -f: Load this as a script (appropriate for a shebang).

Now the jq script itself:

  • .[] |: Pipe each Object from the input stream array for processing
  • ( ... ): Group instructions.
  • "if($link == ": Is just a JSON string literal to be printed as-is ( without the double quotes " since jq has been instructed to produce a raw output with the -j option switch.
  • + ( .num | tostring ): Concatenates with the num member converted to a string, so it can be added to the previous string.
  • + ") { $linkURL = \"": Concatenates with another JSON string literal.
  • + ( .filename | @uri ): Concatenates with the filename member filtered as an URI, so special characters like spaces + & ... will be % encoded.
  • + "\";}\n": Concatenates with another JSON string literal including a newline character escaped as \n to be printed as a raw newline

Example input.json (notice the spaces and quotes to probe test the filter works as intended):

{
   "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"
}

Generated php code from the above input:

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";}

An alternative to produce a PHP switch statement instead:

#!/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
"}"

Result from same 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;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.