字符串“数字”后的数字总结

时间:2012-10-12 19:59:38

标签: full-text-search text-processing

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

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

我想总结一下字符串“number”后面出现的所有数字。如果在字符串“number”之后不是数字,则无关紧要。

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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