我正在学习bash脚本和命令,我需要一些有关此作业的帮助。
我有一个包含以下文本的txt文件,我需要这样做:
我用sed和简单的正则表达式提取名称和数字,但是我不知道如何总结数字,因为来宾有多行记录,如您在txt文件中看到的那样。 注意:我无法使用awk进行处理
这是我的代码:
cat file.txt | sed -E 's/.*([0-9]{1}.[0-9]{1}.[0-9]{1}).*([0-9]{1})/\1 \2/'
结果是:
1.1.1 4
2.2.2 2
1.1.1 1
3.3.3 1
2.2.2 1
这是.txt文件:
Guest 1.1.1 have "4
Guest 2.2.2 have "2
Guest 1.1.1 have "1
Guest 3.3.3 have "1
Guest 2.2.2 have "1
,输出应为:
1.1.1 = 5
2.2.2 = 3
3.3.3 = 1
谢谢您
答案 0 :(得分:0)
我知道您的老师不会允许您使用awk,但是,由于超出了这一练习的范围,您正在尝试学习如何编写shell脚本,因此,仅供参考,这就是您实际上如何在shell脚本中完成此工作的方法:
$ awk -F'[ "]' -v OFS=' = ' '{sum[$2]+=$NF} END{for (id in sum) print id, sum[id]}' file
3.3.3 = 1
2.2.2 = 3
1.1.1 = 5
这是bash内置的等效项,它可能会或可能不会是您在课堂上讨论的内容,因此可能会也可能不是您的老师所期望的:
$ cat tst.sh
#!/bin/env bash
declare -A sum
while read -r _ id _ cnt; do
(( sum[$id] += "${cnt#\"}" ))
done < "$1"
for id in "${!sum[@]}"; do
printf '%s = %d\n' "$id" "${sum[$id]}"
done
$ ./tst.sh file
1.1.1 = 5
2.2.2 = 3
3.3.3 = 1
有关我如何使用关联数组,请参见https://www.artificialworlds.net/blog/2012/10/17/bash-associative-array-examples/。它会比awk脚本慢几个数量级,并且我不能100%地确定它是防弹的(因为shell并非设计用于处理文本,因此存在很多警告和陷阱),但它对于您提供的输入。
答案 1 :(得分:0)
好的-由于这是一个课堂作业,所以我将告诉您我是如何做到的,并让您编写代码。
首先,我对文件进行了排序。然后,我一次只读取一行文件。如果名称更改,我将打印出先前的名称和计数,并将计数设置为该行上的值。如果名称没有更改,我会将值添加到计数中。
答案 2 :(得分:0)
第二个解决方案使用来宾名称作为索引,使用关联数组来保存计数。然后,您只需将新值添加到以来宾名称为索引的数组元素的计数中即可。
最后,遍历数组,打印出索引和值。
要短很多。