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

Perl sed-在第一个正则表达式匹配后替换逗号,perl,text,awk,sed,replace,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

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

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解决方案也会对我有所帮助。这里有一个awk的努力:

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

CSV文件应该在awk中使用一个合适的FPAT变量进行解析,该变量定义了在此类文件中构成有效字段的内容。一旦您这样做了,您就可以在字段上进行迭代以进行所需的替换

gawk 'BEGIN { FPAT = "([^,]+)|(\"[^\"]+\")"; OFS="," } 
       { for(i=1; i<=NF;i++) if ($i ~ /[,]/) gsub(/[,]/,".",$i);}1' file
请参阅以了解如何使用FPAT变量定义和解析CSV文件内容。另请参见执行诸如sed-i之类的就地文件修改。

假设您有: BBBBB.2018_08,XXXXXXXXXXXX,01/01/2014109,07,DF,CCCCCCC

试试这个: awk-F',“{print$1,$2,$3,$4.$5,$6,$7}”文件名| awk'$1=$1'FS=OFS=

输出将是: BBBBB.2018_08,XXXXXXXXXXXX,01/01/2014109.07,DF,CCCCCCC


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

为了像在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'
以下sed将转换带引号的数字字段中的所有十进制分隔符:

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

请参阅:

这可能适用于GNU-sed:

sed -E ':a;s/^([^"]*("[^",]*"[^"]*)*"[^",]*),/\1./;ta' file
此regexp匹配一对中的,并将其替换为。。regexp被锚定到行的开头,因此需要重复,直到没有进一步的匹配可以匹配为止,因此:a和ta命令导致在任何替换成功时迭代替换


注意:解决方案要求所有双引号都匹配,并且不引用双引号,即。\N不会出现在一行中。

如果您的输入始终遵循仅包含一个逗号的带引号字段的格式,则您只需要:

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

如果比这更复杂,那么请参见。

为什么不在第一个awk中定义OFS=?使用当前的解决方案,您将销毁字符串中可能存在的所有空格。我希望它保持干净和简单。另外,我假设除了字段分隔符之外没有空格,但是如果你直接定义OFS,你就不用一个命令:awk'{print$1,$2,$3,$4.$5,$6,$7}'FS=,OFS=,fileWell,你也可以这么做!谢谢您的输入。您不需要if$i~/[,]/-gsub/[,]/。。。如果没有[,]的对手,我什么都不会做。此外,这将删除空字段-在FPAT设置中应使用*s而不是+s。