awk的集合操作实现

需求

有一份人员名单,另有一些已上交的文件,文件名包含人员姓名或编号
问题:谁没交?

思路

这其实是数据结构里的集合操作
若人员名单为集合A,文件名为集合B,则没交的人员集合C=A-B

实例

名单(list.txt):
1 a
2 b
3 c
4 d
5 e
文件列表:
a_1.xls
b.xls
3.xls
谁没交?
d,e

代码

#~ ls 文件夹/ | gawk -f set.awk list.txt -

BEGIN {
    op = "diff"  # 默认求差集;交集为inst
}

#~ 第一个文件为完整名单
FILENAME == ARGV[1] {
    #~ num = $1
    #~ name = $2
    for (i=1; i<=NF; i++) {
        a[NR, i] = $i  # 取出各项
    }
    nf = NF  # 假定项数固定
}

# 名单(模拟二维数组)关联项处理
function handle(a, i, o) {
    for (j=1; j<=nf; j++)
        if ((i, j) in a)  # 判断索引存在
            switch (o) {
                case "print":
                case "inst": print a[i, j]
                    break
                case "diff": delete a[i, j]  # 剩余项为差集
                    break
            }  
}

#~ 后面的为文件列表
FILENAME == ARGV[2] {
    #~ print length(a)
    for (i in a) {
        #~ print bname,bnum,a[i, 2],a[i, 1],$0
        if (match($0, a[i])) {  # 若任一项能匹配(search的中文支持似乎有问题)
            split(i, ss, SUBSEP)
            idx = ss[1]  # 名单索引
            #~ print ss[1],ss[2]
            handle(a, idx, op) 
            next
        }
    }
}

END {
    if (op == "diff") {
        for (i in a)
            print a[i]
    }
}

猜你喜欢

转载自my.oschina.net/u/1044667/blog/896321
今日推荐