如何使用命令行工具将CSV数据解析为唯一列
处理宽CSV转长表(服务器+端口单列/双列格式)
嘿,这个需求太常见了!处理这种第一列是标识、其余列是属性的宽表转长表,命令行有几个非常实用的方案,我给你拆解一下:
方案1:用awk(系统自带,无需额外安装)
awk是处理文本的利器,适合大多数轻量场景,尤其是你的CSV没有复杂特殊字符(比如带引号的字段)时。
假设你的CSV结构是这样的(第一行是表头,也可以没有表头):
server_name,port_1,port_2,port_3,... server01,22,80,443,... server02,22,3306,,...
执行以下命令就能把每台服务器和对应的开放端口拆成单独行:
# 如果有表头,跳过第一行;如果没有表头,去掉 `NR>1` awk -F ',' 'NR>1{ server=$1; for(i=2;i<=NF;i++){ # 过滤空的端口列 if($i != "") print server "," $i; } }' your_large_file.csv > output.csv
这个命令会生成一个双列的CSV,每行是服务器名,端口,如果你想做成单列格式(比如server01:22),把print server "," $i改成print server ":" $i就行。
方案2:用csvkit(专业CSV处理工具,更稳妥)
如果你的CSV包含复杂格式(比如字段带引号、换行),awk可能会出错,这时候用专门的CSV工具csvkit更靠谱。先通过包管理器安装它(比如pip install csvkit或者apt install csvkit)。
有表头的情况:
假设第一列表头是server_name,其余列是端口列:
csv-melt --id-columns server_name your_large_file.csv | csvcut -c server_name,value | csvfilter -c value -x 'is_empty($field)' > output.csv
csv-melt:把宽表转成“服务器名-原列名-端口值”的长表csvcut:只保留我们需要的服务器名和端口值列csvfilter:过滤掉空的端口值
没有表头的情况:
直接指定第一列为ID列:
csv-melt --id-columns 1 your_large_file.csv | csvcut -c 1,3 | csvfilter -c 3 -x 'is_empty($field)' > output.csv
小提示
- 数千列的CSV对这两个工具来说都没问题,awk处理速度更快,csvkit兼容性更强
- 如果需要直接输出到终端查看,可以把最后的
> output.csv去掉,或者加| head看前几行测试效果
内容的提问来源于stack exchange,提问作者user9340382
相关产品推荐
相关产品推荐

