2

Docker Engine API returns container name with / appended

{
    "Id": "8dfafdbc3a40",
    "Names": [
        "/boring_feynman"
    ],
    "Image": "ubuntu:latest",
    "ImageID": "d74508fb6632491cea586a1fd7d748dfc5274cd6fdfedee309ecdcbc2bf5cb82",
    "Command": "echo 1",
    "Created": 1367854155,
    "State": "Exited",
    "Status": "Exit 0",
    "Ports": [{
        "PrivatePort": 2222,
        "PublicPort": 3333,
        "Type": "tcp"
    }],
    "Labels": {
        "com.example.vendor": "Acme",
        "com.example.license": "GPL",
        "com.example.version": "1.0"
    },
    "SizeRw": 12288,
    "SizeRootFs": 0,
    "HostConfig": {
        "NetworkMode": "default"
    },
    "NetworkSettings": {
        "Networks": {}
    },
    "Mounts": [{
        "Name": "fac362...80535",
        "Source": "/data",
        "Destination": "/data",
        "Driver": "local",
        "Mode": "ro,Z",
        "RW": false,
        "Propagation": ""
    }]
}

I want to remove the slash so the response can be used as a table in JQ:

jq -r '(["Names","Image"] | (., map(length*"-"))), (.[] | [.Names, .Image]) | @tsv'

Currently, when I run the above, I get:

jq: error (at <stdin>:1): array (["/boring_feynman"]) is not valid in a csv row
Inian
  • 80,270
  • 14
  • 142
  • 161

1 Answers1

1

The problem is not because of / in the .Names field, but in your expression. For filters like @csv or @tsv to work, the values need to be in a scalar format and in an array. But your expression .Name in of type array.

So basically you are passing this result to the @tsv function

[
  [
    "/boring_feynman"
  ],
  "ubuntu:latest"
]

instead of

[
  "/boring_feynman",
  "ubuntu:latest"
]

So modifying your filter, you can do below for the JSON in question.

jq -r '(["Names","Image"] | (., map(length*"-"))), ([.Names[], .Image]) | @tsv'

or if you still want to remove the /, use gsub() function

jq -r '(["Names","Image"] | (., map(length*"-"))), ([ (.Names[] | gsub("^/";"")), .Image]) | @tsv'
Inian
  • 80,270
  • 14
  • 142
  • 161
  • with jq-1.6, both examples return: jq: error (at input.json:42): Cannot index string with string "Names" – Fábio Almeida Oct 19 '20 at 09:00
  • 1
    @fabioalmeida: Can you drop the `.[] |` before the `(.Names[]` and try? i.e. `jq -r '(["Names","Image"] | (., map(length*"-"))), ([.Names[], .Image]) | @tsv'` – Inian Oct 19 '20 at 09:02
  • I don't see the need in using \.[] | This can probably be stripped out? – Raman Sailopal Oct 19 '20 at 09:03
  • @Irian, i drop .[] | before the (.Names[] and the example worked – Fábio Almeida Oct 19 '20 at 09:20
  • @Inian - Thanks. Worked for me too. Can also guide on how to align the header and columns of the table? – Hammad Butt Oct 19 '20 at 10:43
  • @HammadButt: It gets quite cumbersome to column align the output with `jq`. If you have external tools like `column`. You can just pipe the output from `jq` to column i.e. `jq '..' | column -t ` – Inian Oct 19 '20 at 11:02
  • Also you should consider _accepting_ the answer if it worked as expected. See the SE Help Center link [What should I do when someone answers my question?](https://stackoverflow.com/help/someone-answers) – Inian Oct 19 '20 at 11:10
  • 1
    Thanks for the help! :) It has been marked as accepted. – Hammad Butt Oct 19 '20 at 11:50