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 次下载
17KB
177 行
sumcol
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