使用sed命令更改csv文件中的分隔符

时间:2014-05-07 09:47:49

标签: regex unix sed

我的文件格式如下。

1,"John, Williams",23,USA

2,"Abraham, Lincoln",24,NC

我需要输出格式为

1~"John, Williams"~23~USA

2~"Abraham, Lincoln"~24~NC

我使用sed命令写了一些内容,但它无法正常工作..

 sed "s/\",\"/\"~\"/g"        

但它没有给出正确的格式..

3 个答案:

答案 0 :(得分:1)

如果你的awk版本是上面的Gnu版本4,并支持FPAT的新功能,这里有一个简单的方法:

awk 'BEGIN{FPAT = "([^,]+)|(\"[^\"]+\")"}$1=$1' OFS="~" file

有关FPAT用法的详细信息,请访问:4.7 Defining Fields By Content

4.7 Defining Fields By Content

NOTE: This section discusses an advanced feature of gawk. If you are a novice awk user, you might want to skip it on the first reading.

Normally, when using FS, gawk defines the fields as the parts of the record that occur in between each field separator. In other words, FS defines what a field is not, instead of what a field is. However, there are times when you really want to define the fields by what they are, and not by what they are not.

The most notorious such case is so-called comma separated value (CSV) data. Many spreadsheet programs, for example, can export their data into text files, where each record is terminated with a newline, and fields are separated by commas. If only commas separated the data, there wouldn’t be an issue. The problem comes when one of the fields contains an embedded comma. While there is no formal standard specification for CSV data24, in such cases, most programs embed the field in double quotes. So we might have data like this:

Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA
The FPAT variable offers a solution for cases like this. The value of FPAT should be a string that provides a regular expression. This regular expression describes the contents of each field.

In the case of CSV data as presented above, each field is either “anything that is not a comma,” or “a double quote, anything that is not a double quote, and a closing double quote.” If written as a regular expression constant (see Regexp), we would have /([^,]+)|("[^"]+")/. Writing this as a string requires us to escape the double quotes, leading to:

FPAT = "([^,]+)|(\"[^\"]+\")"
Putting this to use, here is a simple program to parse the data:

BEGIN {
    FPAT = "([^,]+)|(\"[^\"]+\")"
}

{
    print "NF = ", NF
    for (i = 1; i <= NF; i++) {
        printf("$%d = <%s>\n", i, $i)
    }
}

答案 1 :(得分:0)

awk应该:

awk -F, '{for (i=1;i<NF;i++) {if ($i~/"/ && gsub(/"/,"\"",$i)==1) f=!f;printf "%s"(f?",":"~"),$i}print $NF}'
1~"John, Williams"~23~USA

2~"Abraham, Lincoln"~24~NC
a~"foo"~b~c

它会测试,是否在".."内,然后选择~,

同时处理a,"foo",b,c

答案 2 :(得分:0)

sed ':a
s/,\(\([^"]*"[^"]*"\)*[^"]*\)$/~\1/g
t a' YourFile

替换任何双引号对等的<{1}}