从使用awk文件中读取一个元组(reading a tuple from a file with a

2019-10-17 01:22发布

嗨,我需要一个脚本来读取ETH的数量从中断的/ proc /中断文件使用awk,发现每个CPU core.An中断的总数,然后我想在文件的内容bash.The使用它们是;

      CPU0       CPU1       CPU2       CPU3

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

我读本规范AWK此文件:

#!/bin/bash

 FILE="/proc/interrupts"

 output=$(awk 'NR==1 {
 core_count = NF 
 print core_count
 next
}
/eth/ {
 for (i = 2; i <= 2+core_count; i++)
 totals[i-2] += $i
}

END {
 for (i = 0; i < core_count; i++)
 printf("%d\n", totals[i])
}
' $FILE)

core_count=$(echo $output | cut -d' ' -f1)

output=$(echo $output | sed 's/^[0-9]*//')

totals=(${output// / })

在这种方法中,我处理的总核心数,然后每个内核的总中断,以便在我script.But排序他们,我只能处理数以总计阵列艾克此,

    totals[0]=22222
    totals[1]=33333

但我需要将它们作为与CPU内核的名称元组。

    totals[0]=(cPU1,2222)
    totals[1]=(CPU',3333)

我想我必须指定名称的数组和阅读themn来砸在我的SED元组。 我怎样才能做到这一点?

Answer 1:

首先,有没有这样的东西在bash一个“元组”。 和数组是完全平坦的。 这意味着你要么有一个“的标量”可变,或标量中的一个级阵列。

有一些接近你面临的任务。 或者:

  1. 如果您使用的是新的bash不够(4.2 AFAIR),你可以使用关联数组(哈希,地图或者无论你称呼它)。 然后,CPU名称将密钥和数字将值;
  2. 创建一个普通数组(类似Perl的哈希值),其中奇数索引将有钥匙(CPU名),甚至那些 - 值。
  3. 创建两个单独的阵列,一个与CPU名称和其他与价值观,
  4. 创建只是一个单一的阵列,其中一些符号从值分离CPU名称(即=: )。

让我们覆盖的方法2第一:

#!/bin/bash

FILE="/proc/interrupts"

output=$(awk 'NR==1 {
    core_count = NF
    for (i = 1; i <= core_count; i++)
        names[i-1] = $i
    next
}
/eth/ {
    for (i = 2; i <= 2+core_count; i++)
        totals[i-2] += $i
}

END {
    for (i = 0; i < core_count; i++)
        printf("%s %d\n", names[i], totals[i])
}
' ${FILE})

core_count=$(echo "${output}" | wc -l)
totals=(${output})

需要注意的几件事情我已经改变使脚本更简单:

  1. 现在AWK输出`CPU-名编号”,每行一个,通过一个单一的空间分开;
  2. 核心计数不通过AWK输出(以避免预处理输出),而是从行数推导在输出中,
  3. totals两个空间和换行符将被视为空白,并使用分离的值-阵列由平坦的输出创建的。

所得阵列看起来像:

totals=( CPU0 12345 CPU1 23456 ) # ...

遍历它,你可以使用类似(简单的方法):

set -- "${totals[@}}"
while [[ $# -gt 0 ]]; do
    cpuname=${1}
    value=${2}

    # ...

    shift;shift
done

现在让我们修改它的方法1:

#!/bin/bash

FILE="/proc/interrupts"

output=$(awk 'NR==1 {
    core_count = NF
    for (i = 1; i <= core_count; i++)
        names[i-1] = $i
    next
}
/eth/ {
    for (i = 2; i <= 2+core_count; i++)
        totals[i-2] += $i
}

END {
    for (i = 0; i < core_count; i++)
        printf("[%s]=%d\n", names[i], totals[i])
}
' ${FILE})

core_count=$(echo "${output}" | wc -l)
declare -A totals
eval totals=( ${output} )

注意:

  1. 在AWK输出格式已被改变,以适应关联数组语义,
  2. totals被声明为关联数组( declare -A ),
  3. 可悲的是, eval必须用来让bash中直接处理的输出。

所得阵列看起来像:

declare -A totals=( [CPU0]=12345 [CPU1]=23456 )

现在你可以使用:

echo ${totals[CPU0]}

for cpu in "${!totals[@]}"; do
    echo "For CPU ${cpu}: ${totals[${cpu}]}"
done

第三种方法可以做许多不同的方式。 假设你可以允许两个读/proc/interrupts ,你甚至可以这样做:

FILE="/proc/interrupts"

output=$(awk 'NR==1 {
    core_count = NF
    next
}
/eth/ {
    for (i = 2; i <= 2+core_count; i++)
        totals[i-2] += $i
}

END {
    for (i = 0; i < core_count; i++)
        printf("%d\n", totals[i])
}
' ${FILE})

core_count=$(echo "${output}" | wc -l)
names=( $(cat /proc/interrupts | head -n 1) )
totals=( ${output} )

所以,现在的AWK再次只输出计数和名称由庆典从第一行获得/proc/interrupts直接。 此外,也可以从在方法(2),或解析AWK输出一些其他方式获得的单个阵列创建分割阵列。

其结果将是两个数组:

names=( CPU0 CPU1 )
totals=( 12345 23456 )

输出:

for (( i = 0; i < core_count; i++ )); do
    echo "${names[$i]} -> ${totals[$i]}"
done

而最后的办法:

#!/bin/bash

FILE="/proc/interrupts"

output=$(awk 'NR==1 {
    core_count = NF
    for (i = 1; i <= core_count; i++)
        names[i-1] = $i
    next
}
/eth/ {
    for (i = 2; i <= 2+core_count; i++)
        totals[i-2] += $i
}

END {
    for (i = 0; i < core_count; i++)
        printf("%s=%d\n", names[i], totals[i])
}
' ${FILE})

core_count=$(echo "${output}" | wc -l)
totals=( ${output} )

现在的(普通)阵列是这样的:

totals=( CPU0=12345 CPU1=23456 )

你可以解析它,如:

for x in "${totals[@]}"; do
    name=${x%=*}
    value=${x#*=}
    echo "${name} -> ${value}"
done

(注意,现在拆分CPU名称和值在循环发生)。



文章来源: reading a tuple from a file with awk