使用 AWK 喝咖啡

使用一个简单的 AWK 程序来跟踪你的同事们喝咖啡所欠的费用。
188 位读者喜欢这个。
Getting started with Perlbrew

freephotocc 通过 Pixabay CC0

以下内容基于真实故事,尽管一些名称和细节已被更改。

很久以前,在一个遥远的地方,有一个办公室。由于各种原因,该办公室没有购买速溶咖啡。 办公室里的一些员工聚在一起,决定建立一个“咖啡角”。

咖啡角的成员会购买一些速溶咖啡,其他成员会偿还他们。后来,有些人喝的咖啡比其他人多,因此添加了“半个成员”级别:允许半个成员每周喝有限数量的咖啡,并且支付成员支付金额的一半。

管理这个非常痛苦。 我刚刚读了Unix 编程环境,并想练习我的 AWK 编程。 所以我自愿创建一个系统。

步骤 1:我保留了一个成员及其对咖啡角的欠款的数据库。 我以 AWK 友好的格式进行操作,其中字段用冒号分隔

member:john:1:22
member:jane:0.5:33
member:pratyush:0.5:17
member:jing:1:27

上面的第一个字段标识此行的类型(成员)。 第二个字段是成员的姓名(即,没有 @ 的电子邮件用户名)。 下一个字段是他们的会员级别(full=1 或 half=0.5)。 最后一个字段是他们对咖啡角的欠款。 正数表示他们欠钱,负数表示咖啡角欠他们钱。

步骤 2:我保留了咖啡角的输入和输出日志

payment:jane:33
payment:pratyush:17
bought:john:60
payback:john:50

简支付了 33 美元,Pratyush 支付了 17 美元,约翰购买了价值 60 美元的咖啡,咖啡角支付了约翰 50 美元。

步骤 3:我准备好编写一些代码了。 该代码将处理成员和付款,并吐出一个更新的members文件,其中包含新的债务。

#!/usr/bin/env --split-string=awk -F: -f

Shebang (#!) 行需要做一些工作! 我使用 env 命令来允许从 shebang 传递多个参数:具体来说,AWK 的 -F 命令行参数告诉它字段分隔符是什么。

AWK 程序是一系列规则。 (它也可以包含函数定义,但我不需要任何用于咖啡角的函数。)

第一条规则读取 members 文件。 运行命令时,我总是先提供 members 文件,然后再提供 payments 文件。 它使用 AWK 关联数组在 members 数组中记录成员资格级别,在 debt 数组中记录当前债务。

$1 == "member" {
   members[$2]=$3
   debt[$2]=$4
   total_members += $3
}

第二条规则在记录 payment 时减少债务。

$1 == "payment" {
   debt[$2] -= $3
}

Payback 则相反:它增加了债务。 这优雅地支持了意外地给某人太多钱的情况。

$1 == "payback" {
   debt[$2] += $3
}

最复杂的部分发生在有人为咖啡俱乐部购买("bought")速溶咖啡时。 它被视为付款,并且该人的债务减少了相应的金额。 接下来,它计算每个成员的费用。 它遍历所有成员,并根据他们的会员级别增加他们的债务。

$1 == "bought" {
   debt[$2] -= $3
   per_member = $3/total_members
   for (x in members) {
       debt[x] += per_member * members[x]
   }
}

END 模式是特殊的:它只发生一次,当 AWK 没有更多行要处理时。 此时,它会吐出新的 members 文件,其中包含更新的债务级别。

END {
   for (x in members) {
       printf "%s:%s:%s\n", x, members[x], debt[x]
   }
}

除了一个遍历成员并向人们发送提醒电子邮件以支付他们的会费(对于正数债务)的脚本之外,该系统在很长一段时间内都在管理咖啡角。

标签
Moshe sitting down, head slightly to the side. His t-shirt has Guardians of the Galaxy silhoutes against a background of sound visualization bars.
自 1998 年以来,Moshe 一直参与 Linux 社区,帮助举办 Linux“安装派对”。 自 1999 年以来,他一直在编程 Python,并为核心 Python 解释器做出了贡献。 Moshe 自这些术语存在之前就是 DevOps/SRE,他非常关心软件的可靠性、构建可重复性等。

8 条评论

好,回归基础 :-)

过度工程的完美例子。 如果只是让每个人每周投入 5 美元,然后不时地分配剩余的东西,岂不是更容易。

但是,那样有什么乐趣呢。 :D

耶! 使用酷代码进行简单的成本跟踪。
呸! 对于速溶咖啡(难怪你只有 4 个成员...)?

感谢分享,太精彩了。

这难道不是办公室文化中的很多问题吗?

根本无法使用 shebang 行使其工作。 使用以下命令可以正常工作
awk -F":" -f proc.awk members payments

只要我将没有 shebang 的代码放在 proc.awk 文件中并加上一个右括号... env 命令不喜欢我尝试的任何东西。 尝试了 exec,尝试了用引号引起来的 awk 的 bash,厌倦了煮咖啡...

不错^)

嗯,这有点 ... awk ward ;)

Creative Commons License本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.