21

I can find a docker container by name: docker ps --filter='name=mvn_repo'. Is there a way (without resorting to bash/awk/grep etc.) to negate this filter and list all containers except the one with the given name?

Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
Mykola Gurov
  • 8,517
  • 4
  • 29
  • 27
  • 3
    As a workaround I do shell: `docker ps -aq | grep -v $(docker ps -q --filter='name=mvn_repo')`. – Mykola Gurov Aug 12 '15 at 18:06
  • Does this answer your question? [Remove all Docker containers except one](https://stackoverflow.com/questions/40744000/remove-all-docker-containers-except-one) – drypatrick Feb 04 '23 at 12:32

4 Answers4

11

You can use docker inspect to do this, I created a container with --name=test111, it appears as /test111, so if I do

docker inspect -f '{{if ne "test111" .Name }}{{.Name}} {{ end }}' $(docker ps -q) /test111 /sezs /jolly_galileo /distracted_mestorf /cranky_nobel /goofy_turing /modest_brown /serene_wright /fervent_lalande

but if I do a filter with the /, so it becames

docker inspect -f '{{if ne "/test111" .Name }}{{.Name}} {{ end }}' $(docker ps -q) /sezs /jolly_galileo /distracted_mestorf /cranky_nobel /goofy_turing /modest_brown /serene_wright /fervent_lalande

I do not get it.

Kudos to Adrian Mouat for his reference post on docker inspect

http://container-solutions.com/docker-inspect-template-magic/

And, as he says

"(Unfortunately Docker prints a new-line for each container, whether it matches the if or not)." If I put a blank line the formatting is lost.

user2915097
  • 30,758
  • 6
  • 57
  • 59
8

I came here trying to figure out a similar problem... found part of the solution in Mykola Gurov's comment, which I modifed to get to this:

docker ps -aq | grep -v -E $(docker ps -aq --filter='name=mvn_repo' | paste -sd "|" -)

Mykola's solution only works if there is one match with the docker ps filter. So if you've got a whole bunch of containers you want to exclude that match a filter pattern - it will fail because grep can only work on a single expression.

The solution I've provided converts the output of that into a regular expression and then uses grep with extended regexp.

To break it down...

docker ps -aq --filter='name=mvn_repo' | paste -sd "|" -

produces output like this:

d5b377495a58|2af19e0029a4

where this is the result of each of the container id's joined with a | character to formulate a regular expression that can then be used with grep.

Then when used in a sub-shell like this with grep:

grep -v -E $(docker ps -aq --filter='name=mvn_repo' | paste -sd "|" -)

resolves to something like this:

grep -v -E d5b377495a58|2af19e0029a4

then when we can then pipe the the output of docker ps -aq to get something like this:

docker ps -aq | grep -v -E d5b377495a58|2af19e0029a4
Jim
  • 668
  • 8
  • 22
  • This fails if name=mvn_repo does not exist. – FreshMike Nov 04 '20 at 17:18
  • 1
    @FreshMike true, however; if you're scripting you can trap the error and wouldn't need a one liner. If OP's goal is to just have a simple alias to search across a bunch of containers - if it fails because the initial criteria for the filter doesn't exist - who cares? Hence why it's broken down into the pieces - so if you want to script this into more robust operation, it's easily done; just not in a one liner. – Jim Aug 17 '21 at 16:32
5

Is there a way (without resorting to bash/awk/grep etc.) to negate this filter and list all containers except the one with the given name?

The Docker command line reference doesn't mention a way to do this. I therefore conclude that negating a filter is not currently supported by the Docker CLI.

augurar
  • 12,081
  • 6
  • 50
  • 65
  • 2
    Not sure why this is getting downvoted, this was at the time and remains the correct answer to the question. Q: Is negating a filter supported? A: No. – augurar Aug 10 '17 at 18:11
  • 3
    It would be the correct answer if the question was "Does the Docker command line interface support negating filter of docker ps?". But that is not what the OP asked. So you get down voted because you are not answering the question. The OP asked how can he do it. And there are many ways to achive what he wants. – harogaston Jun 27 '19 at 18:33
  • @harogaston Added a quote of the OP's question to clarify what I'm answering. – augurar Jun 27 '19 at 21:26
5

The following command may be used:

comm -2 -3 <(docker ps -aq | sort) <(docker ps -aq --filter='name=mvn_repo' | sort)

Explanation of how the code works:

  • docker ps -aq shows a list of all running containers
  • docker ps -aq --filter='name=mvn_repo' shows a sorted filtered list of containers
  • comm -2 -3 <(... | sort) <(... | sort) takes sorted lists and provides lines unique to the first list (of running containers). See man comm for more details of comm.
Maxim Suslov
  • 4,335
  • 1
  • 35
  • 29