如何从命令行输出中提取值?以USB设备信息输出为例
提取USB设备信息的解决方案
好的,我来帮你搞定这个提取问题!先看看你拿到的输出结构:每个设备的信息被--分隔开,每个设备包含产品名称和序列号两行。咱们可以用Elixir的字符串处理工具一步步解析,或者直接在命令行层面优化输出,两种方案都给你整理好了:
方案一:用Elixir代码处理(推荐,适合集成到项目中)
步骤分解
- 第一步:清洗原始输出:
:os.cmd返回的是二进制数据,先转成UTF-8字符串,再按行拆分,过滤掉空行和--分隔符。 - 第二步:分组设备信息:把剩下的有效行每两个分成一组(每组对应一个设备的产品行+序列号行)。
- 第三步:提取关键值:用正则表达式从每组的两行中分别捕获产品名和序列号。
完整代码示例
defmodule USBDevices do def extract_devices do # 执行命令获取原始输出 raw_output = :os.cmd('usb-devices | grep -A 1 Product=') # 清洗数据:转字符串、拆分行、过滤无效内容 cleaned_lines = raw_output |> to_string() |> String.split("\n") |> Enum.reject(fn line -> line == "" or line == "--" end) # 分组并提取设备信息 cleaned_lines |> Enum.chunk_every(2) |> Enum.map(fn [product_line, serial_line] -> # 用正则捕获产品名 product = Regex.run(~r/S: Product=(.*)/, product_line) |> Enum.at(1) # 用正则捕获序列号 serial = Regex.run(~r/S: SerialNumber=(.*)/, serial_line) |> Enum.at(1) # 返回结构化的Map %{product_name: product, serial_number: serial} end) end end # 调用示例 USBDevices.extract_devices()
代码效果
运行后你会得到一个结构化的设备列表,格式如下:
[ %{product_name: "EHCI Host Controller", serial_number: "0000:00:3d.0"}, %{product_name: "HP Truevision HD", serial_number: "201001010001"}, %{product_name: "xHCI Host Controller", serial_number: "0000:00:16.0"}, %{product_name: "iPhone", serial_number: "1d19427ba66fd77d12a836593af57c21c993f0c9"}, %{product_name: "xHCI Host Controller", serial_number: "0000:00:16.0"} ]
方案二:直接在命令行层面优化输出
如果只是想快速拿到格式化的文本结果,可以用awk简化命令:
usb-devices | grep -A 1 Product= | awk '/Product/ {sub(/S: Product=/, "", $0); p=$0} /SerialNumber/ {sub(/S: SerialNumber=/, "", $0); print p " | " $0}' | grep -v -- "--"
这个命令会直接输出每行是产品名 | 序列号的格式,比如:
EHCI Host Controller | 0000:00:3d.0 HP Truevision HD | 201001010001 xHCI Host Controller | 0000:00:16.0 iPhone | 1d19427ba66fd77d12a836593af57c21c993f0c9 xHCI Host Controller | 0000:00:16.0
内容的提问来源于stack exchange,提问作者D.R
相关产品推荐
相关产品推荐

