替换" *,*"用" **"在csv文件中

时间:2016-01-20 13:39:17

标签: regex bash perl csv replace

我获得了包含大量不同细节的.csv文件,最近又添加了尺寸和纪元值。由于值内的不需要的(,)

,这导致导入工具出现问题

e.g。

LIKE

我想在每一行中替换("")之间的不需要的(,)。我尝试使用sed,tr和其他类型的替换,但这没有帮助。我是否需要使用脚本执行此操作或单个线性替换命令?

此致

7 个答案:

答案 0 :(得分:6)

因为你引用了逗号,所以你需要一个解析器。 var friendCursor = friendUsers.find(); var friend; while ( friendCursor.hasNext() ) { friend = friendCursor.next(); console.log( friend.somefieldhere ); } 可以做到这一点,但它很讨厌,像regex s Text::CSV之类的东西解析得很好。

perl

打印:

#!/usr/bin/env perl

use strict;
use warnings;
use Text::CSV;

my $csv = Text::CSV -> new ( { binary => 1, eol => "\n" } ); 

while ( my $row = $csv -> getline ( \*DATA ) ) {
   #remove commas in fields in the row
   s|,||g for @$row; 
   #print the row. 
   $csv -> print ( \*STDOUT, $row ); 
}

__DATA__
col1,col2,col3,col4,col5,col6
abc,edf,"123,456,789","1,234","133,233,456",20/01/2016
ogfsf,dcfdc,0,"1,456","134,567,456",11/01/2016
jkglt,mnbc,0,0,"132,467,876",05/01/2016

根据需要。您可以使用col1,col2,col3,col4,col5,col6 abc,edf,123456789,1234,133233456,20/01/2016 ogfsf,dcfdc,0,1456,134567456,11/01/2016 jkglt,mnbc,0,0,132467876,05/01/2016 从STDIN读取....或者您可以使用open来执行文件IO。

如果你想要一个专门用于'one-liner'的东西用于脚本(IMO是要求正则表达式解决方案的常用原因):

\*STDIN

上面或多或少地做了以上,并且......好吧,有一个权衡 - perl -ne 'BEGIN{$csv = Text::CSV->new({eol=>"\n"})} $csv->print(\*STDOUT, [map {s|,||gr} do {$csv -> parse ( $_ ); $csv ->fields()}])' filename 位非常清楚,但regex可能有点难以理解:)。

这是:

  • 逐行迭代(文件名或标准输入)
  • 调用`parse

答案 1 :(得分:1)

使用sed:

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

细节:

:a # define the label "a"
s/((,|^)"[^",]*),/\1/ # replace the first comma enclosed between quotes
ta # if something is replaced, go to label "a"

-E(或-r)开关将正则表达式语法设置为允许|的ERE(扩展正则表达式),并避免转义括号内的所有特殊字符。

(,|^)用于检查报价是否真的是开头报价。由于逗号从左到右逐个替换,当匹配时,您可以确定以下引号是开头引号(因为引号内的所有先前逗号都已被替换)。

注意:这假设您的csv文件的引用部分不包含换行符。要处理带有换行符的引用部分,它有点复杂,因为您需要检查引号的数量是否为偶数,如果不是,则需要将下一行附加到模式空间,直到获得偶数引号:

sed -E ':a;/^([^"]|"[^"]*")*$/!{N;ba};:b;s/((,|^)"[^",]*),/\1/;tb' file

处理转义报价:

sed -E ':a;/^([^"]|"[^"]*(""[^"]*)*")*$/!{N;ba};:b;s/((,|^)"[^",]*(""[^",]*)*),/\1/;tb;' file

答案 2 :(得分:1)

为什么不在导出没有的值之前创建列3,4,5?根据你所说的,通过添加不同类型的列来改变导出文件,必须告诉那些进行第一次导出的人必须将其导出为xxxxxxxxxx编号,而不是xxx,xxx,xxx编号。

这是在MS excel或Ooo中快速完成的,现在你正在制作一个代码,这会在问题由第一个用户创建时产生更多问题。

将白皮书放在出口应该如何;文本文件,列等等。它使程序员的生活变得更加容易。

答案 3 :(得分:0)

通过perl,

$ perl -pe 's/,(?!(?:[^"]*"[^"]*")*[^"]*$)//g' file
col1,col2,col3,col4,col5,col6
abc,edf,"123456789","1234","133233456",20/01/2016
ogfsf,dcfdc,0,"1456","134567456",11/01/2016
jkglt,mnbc,0,0,"132467876",05/01/2016

通过python。

>>> import re
>>> with open('/home/gemini/Desktop/sample.txt') as f:
        m = f.read()
        print re.sub('"[^"]*"', lambda x: x.group().replace(',', ''), m)


col1,col2,col3,col4,col5,col6
abc,edf,"123456789","1234","133233456",20/01/2016
ogfsf,dcfdc,0,"1456","134567456",11/01/2016
jkglt,mnbc,0,0,"132467876",05/01/2016

答案 4 :(得分:0)

教导您的导入程序处理引号:

B = []
for line in csv:
    A = line.split('"')#A is now a list of strings in which every other element is within quotes
    inquotes = False
    for item in A:
        if(inquotes):
            B.append(item)
        else:
            C = item.split(',')#This is the regular csv stuff, the one we parse by commas
            for element in C:
                 B.append(C)
        inquotes = not(inquotes)#change state

这有点hacky,但会保留逗号而不是删除它们

答案 5 :(得分:0)

这是一个红宝石单行,会盲目删除引用条目中的任何逗号:

ruby -rcsv -e 'CSV.foreach(ARGV.shift) {|row| puts CSV.generate_line row.map {|elem| elem.delete(",")}}' file.csv
col1,col2,col3,col4,col5,col6
abc,edf,123456789,1234,133233456,20/01/2016
ogfsf,dcfdc,0,1456,134567456,11/01/2016
jkglt,mnbc,0,0,132467876,05/01/2016

如果你有

这样的数据
"hello,world",foo,"1,234"

您需要在字符串字段中保留逗号。在那种情况下

$ cat file.csv
col1,col2,col3,col4,col5,col6
abc,edf,"123,456,789","1,234","133,233,456",20/01/2016
"a,b,c","d,e,f",0,0,0,0

$ ruby -rcsv -e '
    CSV.foreach(ARGV.shift) do |row| 
      puts CSV.generate_line (
        row.map do |elem| 
          elem.match(/^\d+(,\d\d\d)+$/) ? elem.delete(",") : elem 
        end
      ) 
    end
  ' file.csv
col1,col2,col3,col4,col5,col6
abc,edf,123456789,1234,133233456,20/01/2016
"a,b,c","d,e,f",0,0,0,0

答案 6 :(得分:0)

专用的CSV解析器绝对可以做到这一点虽然使用标准shell实用程序是一个简单的gnu-awk解决方案:

awk -v FPAT='"[^"]*"|[^,]*' -v OFS=, '{for(i=1; i<=NF; i++) gsub(/,/, "", $i)} 1' file
col1,col2,col3,col4,col5,col6
abc,edf,"123456789","1234","133233456",20/01/2016
ogfsf,dcfdc,0,"1456","134567456",11/01/2016
jkglt,mnbc,0,0,"132467876",05/01/2016

-v FPAT='"[^"]*"|[^,]*'将每一行分为"..."或非逗号字段。

相关问题