2

我是 bash 新手,想改进。我需要学习从文件或命令输出中读取特定文本。例如,我想从 /proc/interrupts 文件中计算计算机每个内核的总以太网中断数。文件的内容是:

CPU0       CPU1       CPU2       CPU3
0:        142          0          0          0   IO-APIC-edge      timer
1:          1          0          1          0   IO-APIC-edge      i8042
4:        694         18        635         19   IO-APIC-edge      serial
7:          0          0          0          0   IO-APIC-edge      parport0
9:          0          0          0          0   IO-APIC-fasteoi   acpi
12:          1          1          0          2   IO-APIC-edge      i8042
14:          0          0          0          0   IO-APIC-edge      ide0
19:          0          0          0          0   IO-APIC-fasteoi   uhci_hcd:usb3
23:          0          0          0          0   IO-APIC-fasteoi   ehci_hcd:usb1,  uhci_hcd:usb2
46:     347470     119806     340499     108227   PCI-MSI-edge      ahci
47:      33568      45958      46028      49191   PCI-MSI-edge      eth0-rx-0
48:          0          0          0          0   PCI-MSI-edge      eth0-tx-0
49:          1          0          1          0   PCI-MSI-edge      eth0
50:      28217      42237      65203      39086   PCI-MSI-edge      eth1-rx-0
51:          0          0          0          0   PCI-MSI-edge      eth1-tx-0
52:          0          1          0          1   PCI-MSI-edge      eth1
59:     114991     338765      77952     134850   PCI-MSI-edge      eth4-rx-0
60:     429029     315813     710091      26714   PCI-MSI-edge      eth4-tx-0
61:          5          2          1          5   PCI-MSI-edge      eth4
62:    1647083     208840    1164288     933967   PCI-MSI-edge      eth5-rx-0
63:     673787    1542662     195326    1329903   PCI-MSI-edge      eth5-tx-0
64:          5          6          7          4   PCI-MSI-edge      eth5

我需要使用“eth”关键字读取所有中断数,然后找到每个 CPU 核心的总和(无论 CPU 核心名称是什么)。比如CPU0:33568+0+1+28217...什么适合这个?我必须将 awk 或 sed 用于正则表达式吗?如何使用?

4

2 回答 2

3

您可以使用awk它,不需要grep 或任何其他工具,因为 awk 可以自己进行搜索。

更新

基于不同数量的 CPU 列的可能性(请参阅下面的第一条评论),这将起作用:

NR==1 {
  core_count = NF
  print "core count: ", core_count
  next
}
/eth/ {
  for (i = 2; i <= 2+core_count; i++)
    totals[i-2] += $i
}

END {
  print "Totals"
  for (i = 0; i < core_count; i++)
    printf("CPU%d: %d\n", i, totals[i])
}

给出输出:

core count:  4
Totals
CPU0:  2926686
CPU1:  2494284
CPU2:  2258897
CPU3:  2513721

备注

如果第一行仅包含 CPU 标头,则使用NF脚本开头所示的方法将起作用。如果可能存在其他数据,则core_count = gsub(/CPU/, "CPU")可以使用。此外,此脚本依赖于连续的 CPU 列。

于 2012-07-20T12:22:16.933 回答
2

您可以使用过滤掉 eth 行grep,然后使用 awk 求和

例如对于 CPU 1 和 2:

grep eth report | awk '{ CPU0 += $2; CPU1 += $3} END { print CPU0; print CPU1} ' 

请注意,您可以在 awk 中过滤,而不是grep为此使用。

然而,我可能很想在 Perl 中执行此操作,并为每个 CPU 创建一个总和哈希值。这将取决于我想要做到这一点的可扩展性。

于 2012-07-20T12:20:15.833 回答