所以我想做的是:查看示例 CSV:
1,3917,3917,BGP=694|Ethernet=1610|LAG=3,Y
运行脚本后,输出应类似于:
1,3917,3917,BGP=694,Y
1,3917,3917,Ethernet=1610,Y
1,3917,3917,LAG=3,Y
包含附加分隔符的原始 CSV 文件的一行现在转换为 3 行,因为第 4 列中有三个附加字段。
我一整天都在研究这个问题,这就是我想到的。它会起作用吗?
代码:
#!/usr/bin/ksh
if [ $# -ne 1 ];
then echo "Usage: read.sh filename";
exit 1;
fi
file="$1"
while read line
do
IFS='|'
set x $line
while [ a -le #$]
do
a=a+1
echo "`$1`,`$a`"
done
done < $1
答案1
使用 AWK 代替
这个问题用AWK就容易解决很多。我用 GNU AWK 对此进行了测试;如果您使用其他东西,您可能需要对其进行一些调整。
#!/usr/bin/gawk -f
BEGIN { FS = "|" }
{
split( $3, array, /,/ )
print $1 "," array[2]
print $1 "," $2 "," array[2]
print $1 "," $3
}
将脚本存储在某处(例如解析.awk)并确保它是可执行的。然后,您可以在 CSV 文件或标准输入上调用脚本,并收集结果,如下所示:
$ echo '1,3917,3917,BGP=694|Ethernet=1610|LAG=3,Y' | parse.awk
1,3917,3917,BGP=694,Y
1,3917,3917,BGP=694,Ethernet=1610,Y
1,3917,3917,BGP=694,LAG=3,Y
答案2
您所拥有的似乎是一个包含由管道符号分隔的分组值的字段。
您可以使用磨坊主( mlr
) 将这些分组值“分解”为单独的新记录:
$ mlr --csv -N nest --evar pipe -f 4 file
1,3917,3917,BGP=694,Y
1,3917,3917,Ethernet=1610,Y
1,3917,3917,LAG=3,Y
file
这将从无标头 CSV 文件中读取输入,然后应用nest
操作,将第四个字段中以竖线分隔的子字段分解为新记录。
您也可以执行相反的操作,即将第四个字段的值“内爆”到由管道分隔的组合字段中。
$ cat file
1,3917,3917,BGP=694,Y
1,3917,3917,Ethernet=1610,Y
1,3917,3917,LAG=3,Y
$ mlr --csv -N nest --ivar pipe -f 4 file
1,3917,3917,BGP=694|Ethernet=1610|LAG=3,Y
由于 Miller 支持 CSV,因此包含嵌入逗号或换行符字段的数据不会出现问题。