Search code examples
jsonbashjq

Remove last character from json output using JQ


I have a json that looks like this:

{ 
  "HostedZones": [
      {
          "ResourceRecordSetCount": 2,
          "CallerReference": "test20150527-2",
          "Config": {
              "Comment": "test2",
              "PrivateZone": true
          },
          "Id": "/hostedzone/Z119WBBTVP5WFX",
          "Name": "dev.devx.company.services."
      },
      {
          "ResourceRecordSetCount": 2,
          "CallerReference": "test20150527-1",
          "Config": {
              "Comment": "test",
              "PrivateZone": true
          },
          "Id": "/hostedzone/Z3P5QSUBK4POTI",
          "Name": "test.devx.company.services."
      }
  ],
  "IsTruncated": false,
  "MaxItems": "100"
}

And my goal is to fetch a specific Name (in my case it's the test.devx.company.services), however the Name field contains an extra "." at the end that I'd like to remove from the output.

This is what I have so far:

jq --raw-output '.HostedZones[] | select(.Name | test("test")?) | (.Name[:-1] | sub("."; ""))'

The problem with that it is removing the first character from the output also.

So the output currently is: est.devx.company.services (JQ play snippet)

Not sure what I'm doing wrong :/


Solution

  • To remove a single character (or any given number of characters) from the end of a string that somewhere also contains the literal string "test", select it and replace it with a substring that ends before the (nth to) last character, i.e. at the corresponding negative index, here |= .[:-1]:

    jq '(.HostedZones[].Name | select(contains("test"))) |= .[:-1]'
    

    Demo


    To additionally only remove the last character if itself is a dot, or more generally any well-defined substring in final position, either substitute it with the empty string "" by matching against a regex pattern, e.g. [.]$ for a final dot, or use the dedicated rtrimstr function by providing the literal substring, "." in this case:

    jq '(.HostedZones[].Name | select(contains("test"))) |= sub("[.]$"; "")'
    # or
    jq '(.HostedZones[].Name | select(contains("test"))) |= rtrimstr(".")'
    

    Demo or Demo