2013-02-12 1 views
2

Je dispose d'un fichier .csv qui contient en dessous des lignes:sed - comment remplacer une chaîne uniquement sur la partie correspondante des lignes dans un fichier csv?

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

Je voudrais enlever les guillemets et virgules de toutes les colonnes cités afin que le résultat sera quelque chose comme ci-dessous:

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

J'ai réussi à localiser les parties sur lesquelles je veux supprimer la virgule en utilisant la commande ci-dessous, mais je ne pouvais pas comprendre comment faire s /, // g et s/"// g on \ 1

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"# 

Vraiment apprécier si quelqu'un peut aider ici.

Jack

Répondre

1

sed n'est pas approprié pour votre travail. Vous pouvez utiliser Perl et Text::CSV module, mais si vous avez GNU awk vous pouvez utiliser la variable FPAT:

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

Résultats:

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

GNU awk est beaucoup plus puissant que awk/nawk qui vient avec solaris. Bien que ce ne soit pas une option pour moi, j'apprécie quand même votre réponse et je vais sûrement la mettre dans ma boîte à outils pour une utilisation future. Merci Steve! – Jack

1

Pour cette tâche spécifique, la coquille est limitée. Un langage de manipulation de texte avancé comme Perl est plus approprié avec un analyseur CSV, voir:

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; 

Si vous devez supprimer des virgules sur des colonnes particulières, remplacer

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

par

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

oui, Perl est certainement un outil idéal pour ce type de tâche. Cependant, mon environnement est solaris 10 et le perl qui l'accompagne n'a pas les modules Text :: CSV ou Text :: CSV_XS. aussi je n'ai pas le contrôle du serveur (c'est-à-dire que l'installation manuelle de ces modules n'est pas une option). BTW, j'ai aussi testé le code perl que vous avez fourni, cela fonctionne très bien sauf que j'ai dû changer le "tr /, //" en "s /, // g" avant que je puisse le faire fonctionner. – Jack

+0

Etes-vous sûr? Vous pouvez installer des modules sans accès root. Voir http://stackoverflow.com/questions/2980297/how-can-i-use-cpan-as-a-non-root-user –

+0

Vraiment? Je vais essayer d'installer les modules plus tard. Merci beaucoup pour votre contribution, Sputnick! Stackoverlow est un super endroit où je peux toujours trouver une solution aux questions qui me dérangent depuis des heures! – Jack

Questions connexes