我有一个CSV文件,我通过一组awk / sed命令进行管道传输。
CSV文件中的某些行如下所示:
10368,"Verizon DSL",DSL,NY,NORTHEAST,-5,-4,"[1.1 - 3.0]","[0.384 - 0.768]"
其中第8和第9列是表示数值范围的字符串。
如何使用awk
或sed
将这些字段替换为数值?范围的开头或范围的结束?
所以这一行最终会成为
10368,"Verizon DSL",DSL,NY,NORTHEAST,-5,-4,1.1,0.384
或
10368,"Verizon DSL",DSL,NY,NORTHEAST,-5,-4,3.0,0.768
我到removing the brackets,但过去我被卡住了。我考虑拆分“ - ”,但是我文件中的许多行在最后两列中都有一个常规数值,而不是一个范围,这会使事情变得混乱(我不想最终得到一些具有不同数量的列。)
答案 0 :(得分:2)
这是一个sed命令,它将获取每个范围并将其分解为两个字段。它会查找"[A - B]"
之类的字符串,并将其转换为A,B
。如果需要,可以通过更改\1,\2
部分轻松修改为仅使用其中一个值。正则表达式假定所有数字在所需小数位的任一侧至少有一位数。因此,1
,.5
和3.
无效。如果您需要,可以使正则表达式更加适应。
$ cat file
10368,"Verizon DSL",DSL,NY,NORTHEAST,-5,-4,"[1.1 - 3.0]","[0.384 - 0.768]"
$ sed -Ee 's|"\[([0-9]+\.[0-9]+) - ([0-9]+\.[0-9]+)\]"|\1,\2|g' file
10368,"Verizon DSL",DSL,NY,NORTHEAST,-5,-4,1.1,3.0,0.384,0.768
答案 1 :(得分:1)
由于您的数据基于 field ,因此awk
是合理的选择。
请注意,虽然awk
通常不了解双引号字段,但这不是问题,因为双引号字段没有嵌入式 ,
个实例。
#!/usr/bin/env bash
useStart1=1 # set to `0` to use the *end* of the *penultimate* fields' range instead.
useStart2=1 # set to `0` to use the *end* of the *last* field's range instead.
awk -v useStart1=$useStart1 -v useStart2=$useStart2 '
BEGIN { FS=OFS="," }
{
split($(NF-1), tokens1, /[][" -]+/)
split($NF, tokens2, /[][" -]+/)
$(NF-1) = useStart1 ? tokens1[2] : tokens1[3]
$NF = useStart2 ? tokens2[2] : tokens2[3]
print
}
' <<'EOF'
10368,"Verizon DSL",DSL,NY,NORTHEAST,-5,-4,"[1.1 - 3.0]","[0.384 - 0.768]"
EOF
上面的代码产生:
10368,"Verizon DSL",DSL,NY,NORTHEAST,-5,-4,1.1,0.384
修改$useStart1
和$useStart2
的值会产生适当的变化。