读取命令输出或从文件读取

时间:2012-07-20 12:16:43

标签: regex linux bash shell

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

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进行正则表达式吗?

2 个答案:

答案 0 :(得分:3)

你可以使用awk,因为awk可以自己进行搜索,所以没有需要grep或任何其他工具。

<强>更新

根据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列。

答案 1 :(得分:2)

您可以使用grep,然后使用sum using awk过滤掉eth行。

e.g。对于CPU 1和2:

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

请注意,您可以filter within awk,而不是使用grep

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