如何逃脱鱼壳变量用作awk模式?

时间:2016-09-07 10:04:45

标签: awk docker fish

我正在编写一个函数来列出来自给定docker存储库的最新图像:

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

工作得很好......

这是docker images输出

$ 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
…

这是我的预期输出:

$ 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

直到

但是,当我在字符串的末尾添加一些/(斜杠)字符来过滤推送的图像时:

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

问题

如何转义repo变量,以便我以awk模式安全地使用它?

3 个答案:

答案 0 :(得分:3)

解决方案

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

详细信息:诀窍是将$repo传递给awk的变量repo并转义$1

答案 1 :(得分:0)

肮脏的解决方案

使用sed

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

肮脏的原因它不是真正的通用。

全功能

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

答案 2 :(得分:0)

如果您必须使用sed,请完全将awk替换为sed。对于这种情况,它将更清晰&amp;更快(sed的情况并非总是如此......)

sed允许在s命令后将分隔符更改为任何内容。我选择#

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

-n禁止输出,p命令仅在匹配时打印。

(如果您对#有疑问,可以选择任何内容,例如%或表达式中不太可能发生的任何事情)