您用bash 标记了您的问题,所以我会像您在询问如何在 bash 中执行此操作一样回答它,而不是询问要使用哪种语言(这会使问题脱离 StackOverflow 的主题) .
您可以使用内置工具从 system_profiler 解析现有数据。例如,这里是 vendor:product 对的转储,带有“Location ID”和制造商...
#!/bin/bash
shopt -s extglob
while IFS=: read key value; do
key="${key##+( )}"
value="${value##+( )}"
case "$key" in
"Product ID")
p="${value% *}"
;;
"Vendor ID")
v="${value%% *}"
;;
"Manufacturer")
m="${value}"
;;
"Location ID")
l="${value}"
printf "%s:%s %s (%s)\n" "$v" "$p" "$l" "$m"
;;
esac
done < <( system_profiler SPUSBDataType )
这依赖于 Location ID 是每个 USB 设备列出的最后一项这一事实,我尚未最终验证。 (对我来说就是这样。)
如果您想要 (1) 更易于阅读且 (2) 不依赖 bash 并因此更便携(但这不是问题;所有 Mac 都带有 bash),您可能需要考虑做您的使用 awk 而不是纯 bash 进行繁重的工作:
#!/bin/sh
system_profiler SPUSBDataType \
| awk '
/Product ID:/{p=$3}
/Vendor ID:/{v=$3}
/Manufacturer:/{sub(/.*: /,""); m=$0}
/Location ID:/{sub(/.*: /,""); printf("%s:%s %s (%s)\n", v, p, $0, m);}
'
甚至避免将其完全包装在外壳中:
#!/usr/bin/awk -f
BEGIN {
while ("system_profiler SPUSBDataType" | getline) {
if (/Product ID:/) {p=$3}
if (/Vendor ID:/) {v=$3}
if (/Manufacturer:/) {sub(/.*: /,""); m=$0}
if (/Location ID:/) {sub(/.*: /,""); printf("%s:%s %s (%s)\n", v, p, $0, m)}
}
}
请注意,您还可以从system_profiler 获取 XML 格式的输出:
$ system_profiler -xml SPUSBDataType
不过,您需要一个 XML 解析器来处理该输出。而且你会发现在原生 bash 中解析 XML 的工作量很大。