sed-第一次正则表达式匹配后替换逗号

时间:2019-05-20 09:58:09

标签: perl text awk sed replace

我正在尝试对通用格式的行执行以下替换:

BBBBBBB.2018_08,XXXXXXXXXXXXX,01/01/2014,"109,07",DF,CCCCCCCCCCC, .......
如您所见,

问题是它是一个逗号分隔的文件,其中的特定字段包含逗号十进制。我想用一个点代替它。

我尝试过这种方法,以替换比赛后第一次出现的模式,但无济于事,有人可以帮助我吗?

sed -e '/,"/!b' -e "s/,/./"
sed -e '/"/!b' -e ':a' -e "s/,/\./"

先谢谢了。 awk或perl解决方案也会对我有帮助。这很费力:

gawk -F "," 'substr($10, 0, 3)==3 && length($10)==12 { gsub(/,/,".", $10); print}'

这会产生相同的文件。

6 个答案:

答案 0 :(得分:3)

CSV文件应使用适当的awk变量在FPAT中进行解析,该变量定义在此文件中构成有效 field 的内容。完成此操作后,您只需遍历各个字段即可进行所需的替换

gawk 'BEGIN { FPAT = "([^,]+)|(\"[^\"]+\")"; OFS="," } 
       { for(i=1; i<=NF;i++) if ($i ~ /[,]/) gsub(/[,]/,".",$i);}1' file

请参见this answer of mine,以了解如何使用FPAT变量定义和解析CSV文件内容。另请参见Save modifications in place with awk进行sed -i''之类的就地文件修改。

答案 1 :(得分:1)

以下sed将转换带引号的数字字段中的所有十进制分隔符:

 sed 's/"\([-+]\?[0-9]*\)[,]\?\([0-9]\+\([eE][-+]\?[0-9]+\)\?\)"/"\1.\2"/g'

请参阅:https://www.regular-expressions.info/floatingpoint.html

答案 2 :(得分:1)

这可能对您有用(GNU sed):

sed -E ':a;s/^([^"]*("[^",]*"[^"]*)*"[^",]*),/\1./;ta' file

此正则表达式在一对,中匹配一个",并用.代替。正则表达式锚定到行的开头,因此需要重复进行,直到无法再匹配其他匹配为止,因此:ata命令会导致替换被迭代,同时进行任何替换成功。

该解决方案期望所有双引号都匹配并且没有双引号,即\"不在一行中。

答案 3 :(得分:1)

如果您的输入始终遵循仅一个带引号的字段(包含1个逗号)的格式,那么您所需要的就是:

$ sed 's/\([^"]*"[^"]*\),/\1./' file
BBBBBBB.2018_08,XXXXXXXXXXXXX,01/01/2014,"109.07",DF,CCCCCCCCCCC, .......

如果比这更复杂,请参见What's the most robust way to efficiently parse CSV using awk?

答案 4 :(得分:0)

假设您有:     BBBBBBB.2018_08,XXXXXXXXXXXXX,01/01/2014,"109,07",DF,CCCCCCCCCCC

尝试一下:     awk -F',' '{print $1,$2,$3,$4"."$5,$6,$7}' filename | awk '$1=$1' FS=" " OFS=","

输出将是:    BBBBBBB.2018_08,XXXXXXXXXXXXX,01/01/2014,"109.07",DF,CCCCCCCCCCC

您只需要知道字段号即可替换它们之间的字段分隔符。

答案 5 :(得分:0)

要像在perl中一样使用regexp,必须使用-r激活扩展的正则表达式。 因此,如果您要替换所有数字并省略“”符号,则可以使用以下代码:

echo 'BBBBBBB.2018_08,XXXXXXXXXXXXX,01/01/2014,"109,07",DF,CCCCCCCCCCC, .......'|sed -r 's/\"([0-9]+)\,([0-9]+)\"/\1\.\2/g'

如果您只想替换首次出现的内容,则可以使用:

echo 'BBBBBBB.2018_08,XXXXXXXXXXXXX,01/01/2014,"109,07",DF,CCCCCCCCCCC, .......'|sed -r 's/\"([0-9]+)\,([0-9]+)\"/\1\.\2/1'
  

https://www.gnu.org/software/sed/manual/sed.txt