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