linux - linux命令输出一个csv文件(里面有不同的格式)
问题描述
命令输出:
//****** BMC SENSORS ******//
Object Id : 0xF000000
PCIe s:b:d.f : 0000:b2:00.0
Device Id : 0x0b30
Numa Node : 1
Ports Num : 01
Bitstream Id : 0x23000110030506
Bitstream Version : 0.2.3
Pr Interface Id : f3c99413-5081-4aad-bced-07eb84a6d0bb
( 1) Board Power : 58.11 Watts
( 2) 12V Backplane Current : 2.43 Amps
( 3) 12V Backplane Voltage : 12.14 Volts
( 4) 1.2V Voltage : 1.19 Volts
( 6) 1.8V Voltage : 1.81 Volts
( 8) 3.3V Voltage : 3.27 Volts
(10) FPGA Core Voltage : 0.90 Volts
(11) FPGA Core Current : 12.28 Amps
(12) FPGA Die Temperature : 58.50 Celsius
(13) Board Temperature : 43.00 Celsius
(14) QSFP0 Supply Voltage : 0.00 Volts
(15) QSFP0 Temperature : 0.00 Celsius
(24) 12V AUX Current : 2.35 Amps
(25) 12V AUX Voltage : 12.18 Volts
(37) QSFP1 Supply Voltage : N/A
(38) QSFP1 Temperature : N/A
(44) PKVL0 Core Temperature : 0.00 Celsius
(45) PKVL0 SerDes Temperature : 0.00 Celsius
(46) PKVL1 Core Temperature : 72.00 Celsius
(47) PKVL1 SerDes Temperature : 73.50 Celsius
我不需要第一行,序列号。希望左侧部分作为标题,右侧部分分别作为CSV中每个标题的列。
我尝试以不同的方式使用 sed -
sed ///****** BMC SENSORS ******/// fpgainfo bmc
fpgainfo bmc | sed ///****** BMC SENSORS ******/// >> ./fp.csv
sed (1),(2),(3),(4),(6),(8),(10),(11),(12),(13),(14),(15),(24),(25),(37),(38),(44),(45),(46),(47)` fpgainfo bmc
但并没有达到我的预期。请帮助我实现同样的目标。
解决方案
向下滚动到最后一段以获得我的最佳建议。这提供了一些关于您尝试的背景,只是为了在得出结论之前解释什么是错误的。
在你的尝试中,只有中间的那个做了一些远程有用或语法定义明确的事情——但sed
语法仍然是错误的;您需要使用不同的定界符或反斜杠正则表达式中的文字斜杠才能正常工作。
但这sed
可能不是一个好的工具;它的处理模型基本上被限制为一次检查一个输入行。你可以让它执行更具挑战性的处理,但对于初学者来说,这绝对不是一个好的第一个练习。
为此,我可能更喜欢 Awk。如果您知道另一种脚本语言,或者计划开始学习一种(例如 Python),则可能会选择它;但是 awk 足够简单,你可以在半小时内学会它的大部分内容。
无论如何,周围的 shell 脚本看起来都一样;你会想要运行你的命令并将它的输出传递给知道如何将它在标准输入上接收到的行转换为你想要的格式的东西。
fpgainfo bmc | awk ...
那么,这里是一个简单的 Awk 脚本,用于提取(我认为您想说的是)您想要的字段到 CSV 文件中,字段名称位于值之前的标题行中。
awk 'BEGIN { sep=""; n=0 }
/^\( *[1-9][0-9]*\)/ {
# Parse out data; trim trailing whitespace
key = substr($0, 6, 25)
sub(/ +$/, "", key)
value = substr($0, 33)
sub(/ +$/, "", value)
# Normalize index
sub(/^\( +/, "")
if ($1 ~ /^[123468]|1[12345]|2[45]|3[78]|4[4567])\)/) {
printf("%s%s", sep, key)
sep = ","
v[++n] = value }
}
END { printf "\n"; sep="";
for(i=1; i<=n; ++i) {
printf("%s%s", sep, v[i])
sep = "," }
printf "\n"
}'
但这仍然很脆弱,因为它取决于您显示的输出完全代表我们需要处理的所有内容的假设。很容易出现这样的情况,即程序会为了易读性而换行长线,或者根据终端的大小调整列宽。
我不熟悉,fpgainfo
但大多数现代工具都可以选择直接生成机器可读的输出(JSON、YAML、XML 等);如果可以的话,它通常比手工制作解析器来处理像这样的肮脏的人类可读格式要好得多。快速谷歌搜索让我得到https://opae.github.io/0.13.0/docs/fpga_tools/fpgainfo/fpgainfo.html其中提到了一个--json
选项 - 可能会改为(并注意例如jq
可以进一步将其转换为适当的 CSV一个简单的选项)。它的工作量不一定会减少,但它会变得更加健壮,因为格式已记录、明确指定并且专为编程操作而设计。
推荐阅读
- sql-server - 如何将 OPTION (MAXRECURSION 0) 与 cte insert 一起使用到临时表中
- node.js - 构建单水疗根节点应用程序时未创建 Dist 文件夹
- amazon-web-services - 通过 ASG 启动时为 Terraform 提取 EC2 实例 ID
- java - 如何解决 Java SpringBoot Web 应用程序中的 POM.XML 错误?
- reactjs - 在 react-konva 中添加拖放连接器
- sequence - 雪花:试图使一列默认使用序列中的值
- r - 计算线性回归线的斜率
- python - 字符串中的条件替换 - Python
- javascript - 如何在 html 中创建新的容器标签
- python - 如何根据二维形状的一系列输入正确预测一个值?