2012-07-20 98 views
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为正则表达式,以及如何?

回答

3

您可以使用awk这个,有没有需要grep或任何其他工具,因为awk可以自己做搜索。

UPDATE

基于不同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列。

+0

这是一个很好的答案,但是CPU0是静态的。如果我不知道CPU内核的名称和数量,例如,如果它以cPU1开始并且通过CPU9。我必须先阅读核心名称并分配给此脚本的变量,或者是否有方法阅读此脚本 – barp 2012-07-20 12:29:50

+0

@barp请尝试此操作,最好使用不同数量的CPU列,并让我知道这是否适用于您。我在这里使用数组,只是fyi。另外请注意,我打印出脚本第三行中发现的内核数量,如果不需要,可以删除它(认为它可能对调试有帮助)。 – Levon 2012-07-20 12:41:00

+0

从报告的结构来看,NR将足以检测我猜测的CPU数量。 – nshy 2012-07-20 12:46:50

2

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

例如对于CPU 1和2:

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

注意,您可以filter within awk,而不是使用grep这一点。

但是,我可能会试图在Perl中做到这一点,并创建每个CPU的总和哈希值。这取决于我想如何扩展。

+0

这是一个很好的答案,但CPU0是静态的。如果我不知道CPU内核的名称和数量。例如,如果它以cPU1开头并通过CPU9。必须先读取核心名称并分配给变量对于这个脚本,或者有一种方法可以在这个脚本中读取 – barp 2012-07-20 12:29:25