【问题标题】:sed or awk replace first 14 ocurrencessed 或 awk 替换前 14 个匹配项
【发布时间】:2014-11-02 22:34:57
【问题描述】:

我有一个由, 分隔的 csv 文件。不幸的是,最后一列是一个文本字段,一些字符串有逗号,所以当我尝试将 csv 导入 MySQL 时,最后一列有时会被剪切。

我的 csv 文件示例(15 列) - 37k 行

Column1  ----------         Col2 Col3  Col4 ----      Col15   
server.domain.tld,IP,Country,City,(...),text random text, text text

我需要用; 替换除最后一个, 之外的所有内容,因此当我使用; 作为列分隔符将文件导入MySQL 时,字段15 不会被剪切。另一种方法是将前 14 个 ',' 替换为 ';'。

我需要的输出:

Column1  ----------         Col2 Col3  Col4 ----      Col15   
server.domain.tld;IP;Country;City;(...);text random text, text text

已经尝试过:

sed 's/,/;/g1-14'
sed 's/,/;/g{1-14}'
sed 's/,/;/g{1,14}'
sed 's/,/;/!14g'
sed 's/,/;/14g!'
sed 's/,/\1;\2;\3;\4;\5;\6;\7;\8;\9;\10;\11;\12;\13;\14;/'

【问题讨论】:

  • 所以你不想替换最后一个逗号?

标签: bash awk replace sed


【解决方案1】:

您可以将它们全部替换为另一个字符,然后从位置 15 重置:

sed -e 's/,/;/g' -e 's/;/,/15g' file

看一个例子:

$ cat a
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
$ sed -e 's/ /X/g' -e 's/X/ /15g' a
X1X2X3X4X5X6X7X8X9X10X11X12X13X14 15

想法基于Sed: Replace N first occurrences of a character

【讨论】:

    【解决方案2】:

    下面的 Perl 命令会将所有逗号替换为 ;,除了最后一个。

    perl -pe 's/,(?![^,]*$)/;/g' file
    

    示例:

    $ cat f
    server.domain.tld,IP,Country,City,foo,bar,foo,bar,foobar,text random text, text text
    $ perl -pe 's/,(?![^,]*$)/;/g' f
    server.domain.tld;IP;Country;City;foo;bar;foo;bar;foobar;text random text, text text
    

    【讨论】:

      【解决方案3】:

      这是另一个想法:引用最后一个字段:

      sed -r 's/(([^,]*,){14})(.*)/\1"\3"/' <<END
      f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,a,b,c,d
      one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen
      a,b,c,d,e,f,g,h,i,j,k,l,m,n
      less,than,fourteen
      END
      
      f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,"a,b,c,d"
      one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,"fifteen"
      a,b,c,d,e,f,g,h,i,j,k,l,m,n
      less,than,fourteen
      

      【讨论】:

      • 我认为 awk 可能更适合这个awk -F, '$NF="\""$NF"\""' OFS=, file
      • 我不同意,你必须先找到前 N 个字段,然后剩下的就是最后一个字段,即使它包含逗号
      • 很公平,不应该是{14}吗?
      【解决方案4】:

      试试这个 sed 单线:

      sed 's/,/;/g;s/;\([^;]*\)/,\1/'
      

      一个小例子:

      kent$  echo "foo,bar,foo,bar,foo,bar,here"|sed 's/,/;/g;s/;\([^;]*\)/,\1/'
      foo;bar;foo;bar;foo;bar,here
      

      我会添加一个带有s/.../.../ge 的gnu sed,虽然它比上面的行长一点

      sed -r 's/(.*)(,.*)/echo $(echo \1|sed "s:,:;:g")\2/ge'
      

      同样的例子:

      kent$ echo "foo,bar,foo,bar,foo,bar,here"|sed -r 's/(.*)(,.*)/echo $(echo \1|sed "s:,:;:g")\2/ge'
      foo;bar;foo;bar;foo;bar,here
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-31
        • 1970-01-01
        • 2013-06-01
        • 1970-01-01
        • 2023-02-02
        • 2011-01-23
        • 2013-01-23
        • 2010-10-27
        相关资源
        最近更新 更多