Replace SED条件替换

Replace SED条件替换,replace,sed,conditional,Replace,Sed,Conditional,我是SED新手,有一个简单的问题。我以前用过它来替换和删除字符,但这有点不同。我需要消除引号中的逗号,然后消除csv文件中的引号。因此: "5,196,386","99,017",493,21 结果应该是这样的: 5196386,99017,493,21 您需要通过多个s///操作来完成此操作。第一种方法是在引号之间只有逗号和数字时,消除引号对之间的逗号;第二个将删除引号(现在引号之间只有数字): 必须尽可能多地重复第一个操作,直到引号之间可以出现的最大逗号数为止。如果您的价值达到数十亿,您

我是SED新手,有一个简单的问题。我以前用过它来替换和删除字符,但这有点不同。我需要消除引号中的逗号,然后消除csv文件中的引号。因此:

"5,196,386","99,017",493,21
结果应该是这样的:

5196386,99017,493,21

您需要通过多个
s///
操作来完成此操作。第一种方法是在引号之间只有逗号和数字时,消除引号对之间的逗号;第二个将删除引号(现在引号之间只有数字):

必须尽可能多地重复第一个操作,直到引号之间可以出现的最大逗号数为止。如果您的价值达到数十亿,您需要第三份副本。

gnu awk one liner:

awk -v FPAT='([^,]+|"[^"]+")' -v OFS="," '{for(i=1;i<=NF;i++)gsub(/[",]/,"",$i)}7'

awk-v FPAT='([^,]+|“[^”]+”)-v OFS=“,”{for(i=1;i我会使用带有适当CSV解析器的语言。例如:

kent$  awk -v FPAT='([^,]+|"[^"]+")' -v OFS="," '{for(i=1;i<=NF;i++)gsub(/[",]/,"",$i)}7' <<< '"5,196,386","99,017",493,21'
5196386,99017,493,21
echo '"5,196,386","99,017",493,21' | 
ruby -rcsv -ne 'CSV.parse($_) do |row| 
  puts CSV.generate_line(row.map {|e| e.delete(",")})
end'

这应该适用于几乎所有的
awk

echo '"5,196,386","99,017",493,21' | awk 'BEGIN {FS=OFS=""} {for (i=1;i<=NF;i++) {if ($i=="\"") {f=!f;$i=""}; if (f && $i==",") $i=""}}1'
5196386,99017,493,21
echo'5196386',99017',493,21'|awk'BEGIN{FS=OFS=“”}{for(i=1;i这可能适用于您(GNU-sed):

这将在双引号字段周围放置
\n
标记,复制整行,删除双引号和逗号,然后将该行重新放在一起并重复,直到不再需要更改为止

另一种方法是:

sed -r 's/^/\n/;ta;:a;s/\n+$//;t;s/\n\n"/\n/;ta;s/\n"/\n\n/;ta;s/\n\n,/\n\n/;ta;s/(\n+)(.)/\2\1/;ta' file

使用
\n
作为标记,逐字符传递字符串。当下一个字符位于带引号的字段内时,会有两个
\n
的标记。

能否将
[0-9][0-9]*
简化为
[0-9]+
或甚至
\d+
..?这取决于您使用的是
sed
的哪个亚物种。我使用的符号将适用于任何符合POSIX的
sed
;您提出的扩展可用于
sed
的其他变体。我没有意识到
+
是-感谢您的澄清这让我很惊讶,你是这样写的,这就是我问这个问题的原因。现在我明白了。+1-一旦文本操作变得更加复杂,第一个反射(或perl)就是使用
awk
。thx@Floris,事实上大括号可以保存。(FPAT)请注意,
FPAT
是GNU
awk
的一项功能,不一定出现在其他版本的
awk
中;POSIX没有指定它。@JonathanLeffler是的,我想我在回答的一开始就提到了这一点。
    awk '{gsub(/"5,196,386","99,017"/,"5196386,99017")}1' file
5196386,99017,493,21
awk '
BEGIN {                     # Begin block
    FS=OFS=""}              # Set input and output Field separator to "" (nothing) makes loop work on every characters
    {for (i=1;i<=NF;i++) {  # Looping trough line, one and one character at the time
        if ($i=="\"") {     # If a double quote is found do:
            f=!f            # Swap the flag "f" (If "f" is true, you are inside a double quote string
            $i=""}          # Delete the double quote
        if (f && $i==",")   # If "f" is true and we find a comma "," (inside a double quote string):
        $i=""}              # Delete the comma
    }
1                           # Print the line.
' file
sed -r ':a;s/"[0-9,]+"/\n&\n/;T;h;s/[,"]//g;G;s/.*\n(.*)\n.*\n(.*)\n.*\n/\2\1/;ta' file
sed -r 's/^/\n/;ta;:a;s/\n+$//;t;s/\n\n"/\n/;ta;s/\n"/\n\n/;ta;s/\n\n,/\n\n/;ta;s/(\n+)(.)/\2\1/;ta' file
    awk '{gsub(/"5,196,386","99,017"/,"5196386,99017")}1' file
5196386,99017,493,21