Édouard Lopez
Édouard Lopez

Reputation: 43421

How to escape Fish shell variable to use as awk pattern?

I'm writing a function to list my latest images from a given docker repository:

function docker-latest
      set repo $argv[1]
      docker images | awk "/$repo/ && /latest/{print $1}"
  end

Works fine…

Here is the docker images output

$ docker images
REPOSITORY                                       TAG                 IMAGE ID            CREATED             SIZE
coaxisopt_daemon                                 latest              86bd3d602074        17 hours ago        830.7 MB
coaxisopt_daemon                                 v1.0.13             86bd3d602074        17 hours ago        830.7 MB
docker.site.fr:5000/coaxis/coaxisopt_daemon     latest              86bd3d602074        17 hours ago        830.7 MB
<none>                                           <none>              da0e5b0fc2a1        17 hours ago        830.7 MB
docker.site.fr:5000/coaxis/coaxisopt_daemon     <none>              9c0175d7d397        18 hours ago        830.7 MB
…

Here is my output as expected:

$ docker-latest coaxis
coaxisopt_daemon                                 latest              86bd3d602074        17 hours ago        830.7 MB
docker.akema.fr:5000/coaxis/coaxisopt_daemon     latest              86bd3d602074        17 hours ago        830.7 MB

Until

However, when I put some / (slash) character in the end of my string to filter on pushed images:

$ docker-latest coaxis/
awk: cmd. line:1: /coaxis// && /latest/{print }
awk: cmd. line:1:           ^ syntax error

Question

How do I escape the repo variable so I used it safely in awk pattern?

Upvotes: 1

Views: 866

Answers (3)

oliv
oliv

Reputation: 13259

Solution

docker images | awk -v repo="$repo"  '$1 ~ repo && $2 == "latest" {print $1}'

Details: the trick is to pass the $repo through the awk's variable repo and escape $1.

Upvotes: 3

Jean-Fran&#231;ois Fabre
Jean-Fran&#231;ois Fabre

Reputation: 140276

If you have to use sed, then fully replace awk by sed. For this case it will be clearer & faster (not always the case with sed...)

sed allows to change the separator to anything after s command. I chose #.

sed -n "s#\([^ ]*${repo}[^ ]*\) \+latest.*#\1#p"

-n suppresses output, and p command prints only if match.

(If you have problems with #, you can choose anything, like %, or anything unlikely to happen in your expression)

Upvotes: 0

&#201;douard Lopez
&#201;douard Lopez

Reputation: 43421

Dirty solution

Use sed:

echo "coaxis/" | sed 's!/!\\\/!g'

Dirty cause it's not really generic.

Full function

function docker-latest
      set repo (echo "$argv[1]" | sed 's!/!\\\/!g')
      docker images | awk "/$repo/ && /latest/{print $1}"
  end

Upvotes: 0

Related Questions