我有一个带有单词和正数的文本文件,由一些空格分隔,例如
A dog has a ball number 49 number 34 number A
Cats number 58
...
我想总结字符串“数字”之后出现的所有数字。如果在字符串“number”之后不是数字,那么没关系。
例如,在这种情况下,答案将是 49+34+58,即141
.
我有一个带有单词和正数的文本文件,由一些空格分隔,例如
A dog has a ball number 49 number 34 number A
Cats number 58
...
我想总结字符串“数字”之后出现的所有数字。如果在字符串“number”之后不是数字,那么没关系。
例如,在这种情况下,答案将是 49+34+58,即141
.
awk '{ for (i = 1; i <= NF; i++) s = s+$i }; END { print s+0 }' test.txt
awk 读取文件,每行一行。对于每一行,都会{}
执行标记的块。块可以由一个条件保护:正则表达式、...、和BEGIN
,END
它们分别对于第一行和最后一行是“真”。
这意味着 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
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