2013-02-12 59 views
2

我有一個包含以下行的CSV文件:sed - 如何替換一個字符串只在csv文件中的行的匹配部分?

23000747,,2015582,-375080.2254,-375080,-375080 
23000749,,SA1555,"-30,448,276","-30,448,456","-30,448,239" 

我想刪除所有引用的列雙引號和逗號,這樣的結果會像下面:

23000747,,2015582,-375080.2254,-375080,-375080 
23000749,,SA1555,-30448276,-30448456,-30448239 

我設法能夠找到我想用下面的命令刪除逗號的部分,但我無法弄清楚如何在\ 1上執行s /,// g和s /「// g 。

sed 's/\("[-,0-9]*"\)/#\1#/g' 1.txt 

23000747,,2015582,-375080.2254,-375080,-375080 
23000749,,SA1555,#"-30,448,276"#,#"-30,448,456"#,#"-30,448,239"# 

真的很感謝任何人都可以在這裏幫忙。

插孔

回答

1

sed不適合您的工作。您可以使用Perl和Text::CSV module,但如果你有GNU awk可以使用FPAT變量:

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

結果:

23000747,,2015582,-375080.2254,-375080,-375080 
23000749,,SA1555,-30448276,-30448456,-30448239 
+0

GNU awk比solaris自帶的awk/nawk功能強大得多。雖然這不是我的選擇,但仍然很感謝你的回答,我一定會把它放到我的工具箱中供將來使用。謝謝史蒂夫! – Jack 2013-02-13 17:02:08

1

對於此特定任務,shell是有限的。如Perl先進的文本處理語言更適合與CSV解析器,請參閱:

my $file = "/path/to/file.csv"; 

use strict; use warnings; 

use feature qw/say/; 
use Text::CSV; 

my $csv = Text::CSV->new() 
    or die "Cannot use CSV: ".Text::CSV->error_diag(); 

open my $fh, "<:encoding(utf8)", $file 
    or die "$file: $!"; 

while (my $row = $csv->getline($fh)) { 
    map { tr/,// } @$row; 
    say join ",", @$row; 
} 

$csv->eof or $csv->error_diag(); 
close $fh; 

如果您需要刪除特定列逗號,更換

map { tr/,// } @$row; 

通過

map { tr/,// } @$row[3..5]; # array slice (columns N-1) 
+0

誠然,Perl絕對是這類任務的理想工具。但是,我的環境是solaris 10,而且它附帶的perl沒有Text :: CSV或Text :: CSV_XS模塊。我也沒有控制服務器(即手動安裝這些模塊不是一種選擇)。順便說一句,我還測試了你提供的perl代碼,它的工作原理很好,除非我必須在「tr /,//」改爲「s /,// g」之後才能使其工作。 – Jack 2013-02-13 15:49:20

+0

你確定嗎?您可以安裝無root權限的模塊。請參閱http://stackoverflow.com/questions/2980297/how-can-i-use-cpan-as-a-non-root-user – 2013-02-13 15:50:35

+0

真的嗎?我會稍後嘗試安裝這些模塊。非常感謝您的意見,Sputnick! Stackoverlow是一個非常好的地方,我總能找到解決困擾我幾個小時的問題的解決方案! – Jack 2013-02-13 17:11:57

相關問題