1

我有一个带有单词和正数的文本文件,由一些空格分隔,例如

A dog has a ball number 49     number    34 number    A
Cats number   58
...

我想总结字符串“数字”之后出现的所有数字。如果在字符串“number”之后不是数字,那么没关系。

例如,在这种情况下,答案将是 49+34+58,即141.

4

2 回答 2

4
awk '{ for (i = 1; i <= NF; i++) s = s+$i }; END { print s+0 }' test.txt

awk 读取文件,每行一行。对于每一行,都会{}执行标记的块。块可以由一个条件保护:正则表达式、...、和BEGINEND它们分别对于第一行和最后一行是“真”。

这意味着 awk 为每一行执行第一个块(因为它是无人看管的)。

此外,awk 并没有真正的类型系统——所有字符串。但是您可以对字符串使用算术 - 在这种情况下,它们会神奇地转换为数字。如果您对不是数字的字符串进行算术运算,它们的计算结果为“0”。这意味着:“asdf”+ 1 = 1;2+4 = 6;"asdf" + 0 = 0;

变量不必声明 - 并且默认为空字符串,其数值为“0”。

awk 的下一个令人敬畏的地方是它会自动将当前输入行拆分为字段。可以指定字段分隔符,但默认为空格。单个字段可以通过$1, $2, ...访问$NF,即NF字段数。$0是完整输入行的内容。

就这样:您查看当前行的所有“字段”。所有字段的数值(字符串为 0)在变量中累积s。阅读完所有内容 ( END) 后,将打印总和。

编辑:这可能很方便,但并不能真正回答问题,因为它不考虑“数字” - 抱歉。

修复:

awk '{ for (i = 1; i <= NF; i++) if ($i == "number") {s = s+$(++i)} }; END { print s+0 }' test.txt

这样,它也会导致 141 输入,例如:

10 狗有球 号码 49 号码 34 号码 A 猫 1000 号码 58

于 2012-10-12T20:03:56.807 回答
2

number您可以通过设置为记录分隔符来用 awk 分隔输入:

awk -v RS=number '{ sum += $1 } END { print sum }' infile

这是一个 grep、coreutils 和 bc 替代方案:

(<infile grep -Eoi 'number[[:blank:]]+[0-9]+' \
| tr -s '[:blank:]' | cut -d' ' -f2 | head -c -1 \
| tr '\n' '+'; echo
) | bc

输出:

141
于 2012-10-15T04:26:01.137 回答