嗨我需要一个脚本来读取/ proc / interruptts文件中带有awk的eth中断数,并找到每个CPU内核的中断总数。然后我想在bash中使用它们。文件的内容是;
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// / })
在这种方法中,我处理总核心数,然后处理每个CORE的总中断,以便在我的脚本中对它们进行排序。但是我只能处理数组中的数字lke this,
totals[0]=22222
totals[1]=33333
但是我需要将它们作为具有CPU核心名称的元组来处理。
totals[0]=(cPU1,2222)
totals[1]=(CPU',3333)
我认为我必须将名称分配给数组并将其读取为bash作为我的SED中的元组。我怎样才能做到这一点?
答案 0 :(得分:0)
首先,bash中没有'tuple'这样的东西。阵列完全平坦。这意味着你要么有一个'标量'变量,要么有一个级别的标量数组。
您面临的任务有多种方法。之一:
=
或:
)的值分隔开来。让我们首先介绍方法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})
请注意我已经更改的一些内容,以使脚本更简单:
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} )
请注意:
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再次只输出计数,名称是通过bash直接从/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名称和值。)