如何转义 Fish shell 变量以用作 awk 模式?
How to escape Fish shell variable to use as awk pattern?
我正在编写一个函数来列出给定 docker 存储库中我的最新图像:
function docker-latest
set repo $argv[1]
docker images | awk "/$repo/ && /latest/{print }"
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
模式中安全地使用它?
解决方案
docker images | awk -v repo="$repo" ' ~ repo && == "latest" {print }'
详情: 诀窍是通过 awk
的变量 repo
传递 $repo
并转义
.
肮脏的解决方案
使用sed
:
echo "coaxis/" | sed 's!/!\\/!g'
脏,因为它不是真正通用的。
全功能
function docker-latest
set repo (echo "$argv[1]" | sed 's!/!\\/!g')
docker images | awk "/$repo/ && /latest/{print }"
end
如果您必须使用 sed
,则将 awk
完全替换为 sed
。对于这种情况,它会更清晰和更快(sed 并非总是如此...)
sed
允许在 s
命令后将分隔符更改为任何内容。我选择了#
。
sed -n "s#\([^ ]*${repo}[^ ]*\) \+latest.*##p"
-n
抑制输出,p
命令仅在匹配时打印。
(如果您对 #
有疑问,您可以选择任何内容,例如 %
,或者任何不太可能出现在您的表达式中的内容)
我正在编写一个函数来列出给定 docker 存储库中我的最新图像:
function docker-latest
set repo $argv[1]
docker images | awk "/$repo/ && /latest/{print }"
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
模式中安全地使用它?
解决方案
docker images | awk -v repo="$repo" ' ~ repo && == "latest" {print }'
详情: 诀窍是通过 awk
的变量 repo
传递 $repo
并转义 .
肮脏的解决方案
使用sed
:
echo "coaxis/" | sed 's!/!\\/!g'
脏,因为它不是真正通用的。
全功能
function docker-latest
set repo (echo "$argv[1]" | sed 's!/!\\/!g')
docker images | awk "/$repo/ && /latest/{print }"
end
如果您必须使用 sed
,则将 awk
完全替换为 sed
。对于这种情况,它会更清晰和更快(sed 并非总是如此...)
sed
允许在 s
命令后将分隔符更改为任何内容。我选择了#
。
sed -n "s#\([^ ]*${repo}[^ ]*\) \+latest.*##p"
-n
抑制输出,p
命令仅在匹配时打印。
(如果您对 #
有疑问,您可以选择任何内容,例如 %
,或者任何不太可能出现在您的表达式中的内容)