嗨,我需要一个脚本来读取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元组。 我怎样才能做到这一点?
首先,有没有这样的东西在bash一个“元组”。 和数组是完全平坦的。 这意味着你要么有一个“的标量”可变,或标量中的一个级阵列。
有一些接近你面临的任务。 或者:
- 如果您使用的是新的bash不够(4.2 AFAIR),你可以使用关联数组(哈希,地图或者无论你称呼它)。 然后,CPU名称将密钥和数字将值;
- 创建一个普通数组(类似Perl的哈希值),其中奇数索引将有钥匙(CPU名),甚至那些 - 值。
- 创建两个单独的阵列,一个与CPU名称和其他与价值观,
- 创建只是一个单一的阵列,其中一些符号从值分离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})
需要注意的几件事情我已经改变使脚本更简单:
- 现在AWK输出`CPU-名编号”,每行一个,通过一个单一的空间分开;
- 核心计数不通过AWK输出(以避免预处理输出),而是从行数推导在输出中,
- 的
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} )
注意:
- 在AWK输出格式已被改变,以适应关联数组语义,
-
totals
被声明为关联数组( declare -A
), - 可悲的是,
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名称和值在循环发生)。