Generate raw output with headers and block separators in JQ

484 Views Asked by At

Using JQ, I need to convert JSON objects to a very specific format called zmp, which looks like this:

selectMailbox     [email protected]
modifyFolderFlags /Inbox       ""
modifyFolderFlags /Inbox/teste ""

selectMailbox     [email protected]
modifyFolderFlags /Inbox ""
modifyFolderFlags /Sent  ""

With this program:

jq -r '.. | objects | select(.flags == "i" or .flags == "#i") | "selectMailbox \(input_filename)","modifyFolderFlags \(.path) \"\" "' *

I was able to output:

selectMailbox     [email protected]
modifyFolderFlags /Inbox       ""
selectMailbox     [email protected]
modifyFolderFlags /Inbox/teste ""
selectMailbox     [email protected]
modifyFolderFlags /Inbox ""
selectMailbox     [email protected]
modifyFolderFlags /Sent  ""

As you see, it outputs selectMailbox multiple times and it's missing the block separator (blank line).

Below are sample inputs.

/tmp/jq/[email protected]

{
  "path": "/",
  "subFolders": [
    {
      "flags": "#",
      "path": "/Drafts",
      "subFolders": []
    },
    {
      "flags": "#i",
      "path": "/Inbox",
      "subFolders": [
        {
          "flags": "i",
          "path": "/Inbox/teste",
          "subFolders": []
        }
      ],
      "unreadCount": 0
    },
    {
      "path": "/Sent",
      "subFolders": []
    }
  ],
  "unreadCount": 0
}

/tmp/jq/[email protected]

{
  "path": "/",
  "subFolders": [
    {
      "flags": "#i",
      "path": "/Inbox",
      "subFolders": []
    },
    {
      "flags": "#i",
      "path": "/Sent",
      "subFolders": []
    },
    {
      "flags": "#",
      "path": "/Trash",
      "subFolders": []
    }
  ],
  "unreadCount": 0
}
1

There are 1 best solutions below

0
EchoMike444 On

You was very close of the solution .

When you have a list of files , you can use jq -slurp to create a big array with all contents of your files .

But because in your case you care about the filename a alternative is concatenate the content of file with the filename in one object .

in your case for example :

jq  -r '{"email":input_filename} + .' * 

and after you can apply almost your solution

jq  -r '{"email":input_filename} + . | 
        "selectMailbox \(.email)",
          (..|objects | select(.flags == "i" or .flags == "#i") |
                          "modifyFolderFlags \(.path) \"\" " 
          ),"" ' *