我正在尝试解析
lspci -k
每台设备输出。换句话说,使用此示例输出:
00:00.0 Host bridge: Intel Corporation 4th Gen Core Processor DRAM Controller (rev 06)
Subsystem: Gigabyte Technology Co., Ltd Device 5000
00:02.0 VGA compatible controller: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller (rev 06)
Subsystem: Gigabyte Technology Co., Ltd Device d000
Kernel driver in use: i915
00:03.0 Audio device: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor HD Audio Controller (rev 06)
Subsystem: Gigabyte Technology Co., Ltd Device 5000
Kernel driver in use: snd_hda_intel
00:16.0 Communication controller: Intel Corporation 8 Series/C220 Series Chipset Family MEI Controller #1 (rev 04)
Subsystem: Gigabyte Technology Co., Ltd Device 5001
Kernel driver in use: mei_me
我希望能够单独遍历每个文件和相关信息。我的正则表达式我用来检测格式??:??。?其他地方是:
grep -E '^[0-9]\w:[0-9]\w\.[0-9]' <<< "$s" | awk -F ' ' '{print $1}'
其中$ s将是此格式列表中有多少设备。我使用这个,因为我有不同格式的非PCI设备。
在这种情况下,我以为我可以得到每个匹配的行号,所以将上述语句输入
grep -n
然后使用sed从一个区域切换到下一个区域,但我觉得这不是一个有效的方法来解决这个问题。有什么建议?
我正在考虑的另一个解决方案是逐行读取并将空白转换为某个符号:例如。
tr ' ' '%'
如果一行以此开头,则包含该行。然而,这可能会变得棘手,因为我需要在循环外部使用外部变量。当然我也可以在正则表达式的每个实例之后添加一个\ n然后只需设置:
IFS=$'\n'
鉴于它们是标签,
tr $'\t' 'x'
运作良好。但是,我觉得最有效的方法仍然是以某种方式切割整个部分然后grep我需要的信息,而不是逐行跟随随机变量。
答案 0 :(得分:3)
以下代码将每个条目从lspci -k
拆分为多个部分:
$ /sbin/lspci -k | awk -F'\t' 'NF == 1 { ++n; f = 0 } { a[n, ++f] = $NF }
END {
for (i = 1; i <= n; ++i) {
print "section", i; f = 0; while (a[i, ++f]) print a[i, f]; print ""
}
}'
通过将输入字段分隔符设置为制表符,我们可以根据它们有多少字段来标识哪些行是新节的开头;每个部分的开头只有1个字段。
END
块中的代码演示了使用两个索引节号和字段号<可以在数组a
中到达每个字段的事实/ em>的。它只是遍历每一个,但你可以自定义逻辑,以便在匹配模式时打印给定字段。
答案 1 :(得分:1)
您是否仅限于lspci -k
?例如,请参阅lspci -mm
和lspci -vkmm
,它们更易于解析。
我不确定你的最终目标是什么,但我做了一个你可能会感兴趣的例子。只要你确实不限于lspci -k
。
#!/bin/sh
for slot in `lspci -mm | cut -d " " -f 1`; do
driver=`lspci -vkmm -s $slot | grep "^Driver:" | cut -f 2`
if [ -n "$driver" ]; then
filename=`/sbin/modinfo --filename $driver 2>/dev/null`
echo $slot $driver $filename
fi
done