#command-line-tool #sum #column #numbers #hex #unix-style #text

bin+lib sumcol

用于计算数字列的总和的命令行工具

4 个版本

0.1.3 2023 年 12 月 18 日
0.1.2 2023 年 12 月 14 日
0.1.1 2023 年 11 月 10 日
0.1.0 2023 年 11 月 10 日

964命令行实用程序

每月 40 次下载

MIT/Apache

17KB
177

sumcol

sumcol CI sumcol crates.io

sumcol 是一个简单的 Unix 风格命令行工具,用于从文本列中求和数字。它是替代传统的 Unix-isms,如 awk '{s += $3} END {print s}'(打印第三列空格分隔的数字的总和),而不需要所有这些冗长。

快速安装

$ cargo install sumcol

示例

注意:如果您没有在您的路径中安装 sumcol,您可以直接从这个仓库中运行以下命令,用 sumcol 替换 cargo run -q --

帮助

$ sumcol -h
A command-line tool to sum a column of numbers.

Usage: sumcol [OPTIONS] [FILES]...

Arguments:
  [FILES]...  Files to read input from, otherwise uses stdin

Options:
  -f, --field <FIELD>          The field to sum. If not specified, uses the full line [default: 0]
  -x, --hex                    Treat all numbers as hex, not just those with a leading 0x
  -d, --delimiter <DELIMITER>  The regex on which to split fields [default: \s+]
  -v, --verbose                Print each number that's being summed, along with some metadata
  -h, --help                   Print help
  -V, --version                Print version

计算文件大小

在这里,我们将计算当前目录中所有文件的大小

$ ls -l
total 48
-rw-r--r--  1 greg  staff  14938 Nov 10 13:56 Cargo.lock
-rw-r--r--  1 greg  staff    399 Nov 10 15:06 Cargo.toml
-rw-r--r--  1 greg  staff   1871 Nov 10 15:16 README.md
drwxr-xr-x  3 greg  staff     96 Nov 10 11:55 src
drwxr-xr-x@ 6 greg  staff    192 Nov 10 11:59 target
drwxr-xr-x  3 greg  staff     96 Nov 10 11:59 tests

大小显示在第 5 列(从 1 开始计数),因此我们可以这样使用 sumcol

$ ls -l | sumcol -f5
17469

这与经典的 awk 表达式等价(但更简洁)

$ ls -l | awk '{s += $5} END {print s}'
17469

计算所有输入

有时您会使用其他工具提取数字列,在这种情况下,您仍然可以使用不带参数的 sumcol 简单地计算所有输入。使用上面的文件列表,我们可以这样做

$ ls -l | awk '{print $5}' | sumcol 
17469

计算十六进制数

程序员经常处理以十六进制形式编写的数字。通常形式为 0x123abc 或甚至简单地 0000abcd。当 sumcol 看到以 0x 开头的数字时,它始终假设它是十六进制形式,并相应地解析它。但是,没有前缀的十六进制数需要我们告诉 sumcol 使用十六进制。

在这个例子中,我们将对编译后的 sumcol 二进制文件中每个部分的尺寸进行求和。我们可以使用 objdump 命令查看这些信息。

$ objdump -h target/release/sumcol

target/release/sumcol:     file format mach-o-arm64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         0014c350  0000000100000c0c  0000000100000c0c  00000c0c  2**2
                  CONTENTS, ALLOC, LOAD, CODE
  1 __TEXT.__stubs 000003b4  000000010014cf5c  000000010014cf5c  0014cf5c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .const        0004f458  000000010014d310  000000010014d310  0014d310  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 __TEXT.__gcc_except_tab 0000cae8  000000010019c768  000000010019c768  0019c768  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  4 __TEXT.__unwind_info 000087c8  00000001001a9250  00000001001a9250  001a9250  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  5 .eh_frame     0002e5e0  00000001001b1a18  00000001001b1a18  001b1a18  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 __DATA_CONST.__got 00000280  00000001001e0000  00000001001e0000  001e0000  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  7 __DATA_CONST.__const 0002c9c0  00000001001e0280  00000001001e0280  001e0280  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  8 .data         00000028  0000000100210000  0000000100210000  00210000  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  9 __DATA.__thread_vars 00000108  0000000100210028  0000000100210028  00210028  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 10 __DATA.__thread_data 00000040  0000000100210130  0000000100210130  00210130  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 11 __DATA.__thread_bss 00000090  0000000100210170  0000000100210170  00210170  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 12 __DATA.__common 00000038  0000000100210200  0000000100210200  00000000  2**3
                  ALLOC
 13 .bss          00000148  0000000100210238  0000000100210238  00000000  2**3
                  ALLOC

在这里,我们可以看到尺寸位于第三个字段,并且它以没有前缀 0x 的十六进制形式书写。让我们看一下第三个字段

$ objdump -h target/release/sumcol | awk '{print $3}'

format


Size
0014c350
LOAD,
000003b4
LOAD,
0004f458
LOAD,
0000cae8
LOAD,
000087c8
LOAD,
0002e5e0
LOAD,
00000280
LOAD,
0002c9c0
LOAD,
00000028
LOAD,
00000108
LOAD,
00000040
LOAD,
00000090
LOAD,
00000038

00000148

糟糕。这里既有数字也有非数字。幸运的是,sumcol 可以轻松处理这个!它默默地忽略非数字,将它们视为 0。那么我们来看看我们得到什么答案

$ objdump -h target/release/sumcol | sumcol -f3
[2023-11-10T21:02:06Z WARN  sumcol] Failed to parse "0014c350". Consider using -x
[2023-11-10T21:02:06Z WARN  sumcol] Failed to parse "000003b4". Consider using -x
[2023-11-10T21:02:06Z WARN  sumcol] Failed to parse "0004f458". Consider using -x
[2023-11-10T21:02:06Z WARN  sumcol] Failed to parse "0000cae8". Consider using -x
[2023-11-10T21:02:06Z WARN  sumcol] Failed to parse "000087c8". Consider using -x
[2023-11-10T21:02:06Z WARN  sumcol] Failed to parse "0002e5e0". Consider using -x
[2023-11-10T21:02:06Z WARN  sumcol] Failed to parse "0002c9c0". Consider using -x
732

有趣的是,sumcol 在上面的例子中默默地忽略了非数字如 LOAD,但是在这里它警告我们它看到了看起来像是十六进制数字的字符串,但我们没有告诉它将数字解析为十六进制。让我们按照建议使用 -x 重新尝试。

$ objdump -h target/release/sumcol | sumcol -f3 -x
0x20C3AC

注意:如果十六进制数字以前缀 '0x 开头,sumcol 将会无声地正确解析它们并省略警告。

调试

如果 sumcol 似乎没有正确工作,您可以自由地查看 github 上的代码(它相当直接),或者使用 -v--verbose 标志运行它,或者甚至启用 RUST_LOG=debug 环境变量。例如

$ printf "1\n2.5\nOOPS\n3" | sumcol -v
1       # n=Integer(1) sum=Integer(1) cnt=1 radix=10 raw_str="1"
2.5     # n=Float(2.5) sum=Float(3.5) cnt=2 radix=10 raw_str="2.5"
0       # n=Integer(0) sum=Float(3.5) cnt=2 radix=10 raw_str="OOPS" err="ParseFloatError { kind: Invalid }"
3       # n=Integer(3) sum=Float(6.5) cnt=3 radix=10 raw_str="3"
==
6.5

每行显示的元数据是

名称 描述
n 解析后的数值
sum 包括当前 n 在内的累积和
cnt 成功解析的数字的累积计数。如果数字解析失败并使用 0 替换,则它将不包括在 cnt
radix 尝试将数字解析为整数时使用的基数
raw_str 解析的原始字符串数据
err 如果存在,这显示了尝试将字符串解析为数字时的错误

这应该足以帮助您调试您看到的问题。但是,如果这还不够,请尝试使用 RUST_LOG=debug

依赖关系

~4–15MB
~156K SLoC