awk删除docker历史镜像

本文已迁移至 segmentfault

背景

虽然对awk早有耳闻,据说是个很强大的工具,但一直没机会去了解和使用,最近碰到一个需求,用awk轻松解决,才真正一窥它的厉害。
需求是这样的,应用每次升级都会构建一个新的容器镜像,时间久了,服务器上会积累很多历史镜像,而且因为镜像本身比较大,磁盘消耗特别快,因此需要写一个脚本定期保留最近N个镜像,清除其余历史镜像。
初步列了以下方案

  1. 用java实现(擅长java~~),通过重定向将docker images的输出传给java,java处理完后执行系统命令清除镜像。
  2. 用python处理。
  3. 用bash处理。
    java方案虽然可行,但想想代码量就不小,既要处理字符串,又要调用系统命令,而且把java拿来做这种事,总感觉怪怪的。pass。
    python不熟,又懒得去学,学完之后估计很长时间不会再用,下次用的时候还得去学,性价比不高,pass。
    最理想的就是bash,正宗的脚本语言,但是否有足够能力处理字符串,需要做技术调研,这时想到了awk。

awk介绍

awk不只是linux的一个工具,由于awk脚本具有编程语言三要素,顺序,循环,判断,awk还是一门编程语言,主要用于数据处理和数据计算。awk对文本进行行扫描,以行为单位进行处理,按照以下逻辑进行处理

pattern { action }
pattern { action }
....

其中pattern是匹配条件,actionpattern匹配后执行的动作。
上面提到awk对文本以行为单位进行处理,读取行后,awk默认以空格为切割符对行进行切割(split)操作并按顺序存放在变量$1$2,$3....中,其中$0表示完整行数据,这些变量可以用于patternaction
举个例子,比如用ps -ef列出目前系统进程

zhengjianfengdeMacBook-Pro:shell asan$ ps -ef
  UID   PID  PPID   C STIME   TTY           TIME CMD
    0     1     0   0 17 418  ??        21:55.75 /sbin/launchd
    0    37     1   0 17 418  ??         1:50.35 /usr/libexec/UserEventAgent (System)
    0    38     1   0 17 418  ??         0:37.59 /usr/sbin/syslogd
    0    40     1   0 17 418  ??         0:14.22 /System/Library/PrivateFrameworks/Uninstall.framework/Resources/uninstalld
    0    41     1   0 17 418  ??         0:09.93 /usr/libexec/kextd
    0    42     1   0 17 418  ??         4:15.97 /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/FSEvents.framework/Versions/A/Support/fseventsd
    0    44     1   0 17 418  ??         0:36.08 /opt/cisco/anyconnect/bin/vpnagentd -execv_instance
   55    48     1   0 17 418  ??         0:03.84 /System/Library/CoreServices/appleeventsd --server

如果我们想要打印出第二列PID的值可以这么写

zhengjianfengdeMacBook-Pro:shell asan$ ps -ef|awk '{print $2}'
PID
1
37
38
40
41
42
44
48

如果想要打印PID大于40值可以这么写

zhengjianfengdeMacBook-Pro:shell asan$ ps -ef|awk '$2>40 {print $2}'
PID
41
42
44
48

本文不是awk入门教程,如果想了解更多awk基本用法,可以阅读以下两篇文章:
http://awk.readthedocs.io/en/latest/chapter-one.html
http://www.runoob.com/linux/linux-comm-awk.html

实现

获取目前系统镜像列表可以通过命令docker images获取,输出格式如下

[root@definesys /]# docker images
REPOSITORY                                                   TAG                 IMAGE ID            CREATED             SIZE
docker.io/xxxxx-authority-ms                                 v1.0.3              02da1a24ac2c        4 days ago          692 MB
docker.io/xxxxx-authority-ms                                 v1.0.2              4a36396f0fea        4 days ago          692 MB
docker.io/xxxxx-uc-user-ms                                   v.1.1.11            6f0db317c7a9        5 days ago          695 MB
docker.io/xxxxx-uc-user-ms                                   v.1.1.10            26983c00bb73        6 days ago          695 MB
docker.io/xxxxx-uc-user-ms                                   v1.1.9              f21d59255405        7 days ago          695 MB
  1. 获取镜像列表
    第一步就是要先获取系统的镜像列表,也就是对REPOSITORY进行去重操作,awk去重有个经典的写法。
awk '!a[$0]++ {print $0}'

声明一个hash数组a并且以$0即行数据为key,第一次a[$0]值是未定义的(undef)取反后为true输出,++对a[$0]进行赋值,赋值后a[$0]值为1,第二次a[$0]为1,取反后为0,0++还是0不输出。
对镜像列表进行去重操作可以以镜像名称(REPOSITORY)为key进行去重

docker images|awk '!a[$1]++ {print $1}'
  1. 获取历史镜像
    要保留最近N个镜像清除历史镜像,其实就是保留数据前N行,awk有个内置变量NR保存当前处理行编号。结合第一步获取的镜像名称可以先grep出指定镜像列表,再用awk进行筛选.
docker images|grep $image|awk 'NR > 4 {printf "%s:%s:%s\n",$1,$2,$3}'
  1. 完整脚本
#!/bin/sh
#create by jianfeng.zheng
#group docker images
for image in `docker images|awk '!a[$1]++ {print $1}'`
do
        for m in `docker images|grep $image|awk 'NR > 4 {printf "%s:%s:%s\n",$1,$2,$3}'`
        do
                id=`echo $m|awk -F ":" '{print $3}'`
                ##do delete
                echo 'delete docker== > '$m
        done
done

结语

awk还有很多功能待挖掘,但可以肯定的是,以后Linux上数据处理的工作,首选方案就是awk。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,585评论 18 139
  • 转载 原文的排版和内容都更加友好,并且详细,我只是在这里贴出了一部分留作自己以后参考和学习,如希望更详细了解AWK...
    XKirk阅读 3,185评论 2 25
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 12,128评论 2 34
  • 目录: 1关键字 1、nonnull:不能为空(用来修饰属性,或者方法的参数,方法的返回值) ios系统使用这个属...
    二斤寂寞阅读 728评论 0 1
  • 好脾气都是磨出来的,坏脾气都是惯出来的。 脾气太好的人,总是一味地去委曲求全,总是为别人想的多,总是一味地去忍让。...
    小王子大梦想阅读 3,985评论 35 98