J'ai big_file.csv contenant un tas d'informations de l'entreprise. Voici un snippet Je n'ai besoin que des champs de nom de l'entreprise et de l'entreprise, donc j'ai procédé aux éléments suivants: p> comme vous pouvez le voir Et je comprends pourquoi) la troisième entrée dans le Big_File.csv est coupée après la première virgule qui fait partie du nom de l'entreprise. Je sais comment supprimer dans SED la première virgule (mais cela briserait toute la structure de la CSV), alors je me demandais si l'un d'entre vous savait comment supprimer la virgule de la première (c'est toujours la position 1) de sorte que la sortie intermédiaire que je recherche est la suivante: p> mais cette dernière ligne devient: p> Une fois cette sortie intermédiaire, j'ai besoin de nettoyer la société de tous les caractères non numériques non alpha-numéros dans le nom et les espaces principaux - ce qui fonctionne très bien avec ceci: p> À la fin, mon fichier doit être: p> " , avec les virgules, ou non et des caractères non alphanum! " code>. p>
10 Réponses :
Une solution avec Ma suggestion serait d'utiliser des langages de programmation tels que awk code>
r code>,
python code >,
perl code> pour ces tâches p> p>
Peut-être que cela aide p> awk code> est votre ami
C'est presque ce que je cherchais - mais la troisième ligne comprend toujours cette virgule supplémentaire après le conseil!
Il est toujours préférable de travailler avec des données structurées telles que les fichiers CSV avec des virgules intégrées dans des champs utilisant des outils qui sont en train de conscience du format au lieu d'essayer de pirater quelque chose avec des expressions régulières (identiques avec XML, JSON, etc.) . À long terme, il est beaucoup plus facile et vous fera économiser une tonne de douleur traitant de cas de bord et de données impairs qui ne correspondent pas exactement à vos attentes.
Le CSVKIT Ensemble d'utilitaires dispose d'un tas d'outils de ligne de commande utiles et est couramment disponible via des gestionnaires de paquets OS: P>
$ perl -MText::AutoCSV -e 'Text::AutoCSV->new(out_fields => [ "COMPANYNAME", "COMPANYNUMBER" ], read_post_update_hr => sub { my $hr = shift; $hr->{"COMPANYNAME"} =~ s/[^[:alnum:]\s]+//g; $hr->{"COMPANYNAME"} =~ s/^\s+//; })->write();' < blah.csv | sed -e 's/"//g' CompanyName,CompanyNumber 1 AVAILABLE LOCKSMITH LTD,05905727 NSPIRED LIMITED,06019953 CENTRE FOR COUNSELLING PSYCHOTHERAPY AND TRAINING LTD,07981734
Salut Shawn - Je reviens à vous après un certain temps, car je me trouve maintenant pour effectuer la même opération (éliminer les virgules supplémentaires dans un CSV ci-joint dans des devis doubles) non seulement sur les 1er colonnes (ici c'était le nom de la société) mais sur tout Colonnes. Seriez-vous si gentil de m'aider à nouveau? Merci :)
Semblable à la solution de @ Sonny, mais à l'aide de la fonction cette sortie: p> gsub code> de GNU's awk pour couper les guillemets et les virgules de la sortie par votre attente de sortie et donner la priorité aux champs conçus dans des guillemets sur ceux qui ne sont pas :
La méthode sed 's/,\ / /g' big_file.csv|xargs -L1|cut -d, -f1,2
Salut! Merci pour tout ce travail! Il finit par se débarrasser du numéro de la société de la troisième colonne, et la virgule supplémentaire après le conseil est toujours là.
SED 'S /, \ / / G' BIG_FILE.CSV | xargs -l1 | Cut -D, -F1,2 code> Cela a fonctionné comme un charme!
J'ai essayé cela et cela a très bien fonctionné - mais j'ai dû passer à Perl car il prenait plus de 10 minutes pour analyser le fichier.
Utilisation de Perl
$ perl -lne ' if($.>1) { /^"(.+?)","(.+?)"/ ;$x=$1;$y=$2; $x=~s/[,]//g; print "$x,$y" } else { print } ' big_file.csv CompanyName, CompanyNumber,RegAddress.CareOf,... ! # 1 AVAILABLE LOCKSMITH LTD,05905727 !NSPIRED LIMITED,06019953 CENTRE FOR COUNSELLING PSYCHOTHERAPY AND TRAINING LTD,07981734 $
avec GNU AWK pour FPAT:
$ cat tst.awk BEGIN { FPAT="\"[^\"]+\"|[^,]*"; OFS="," } NR == 1 { print; next } { for (i=1; i<=NF; i++) { gsub(/[^[:alnum:]]+/," ",$i) gsub(/^ | $/,"",$i) } print $1, $2 } $ awk -f tst.awk file CompanyName, CompanyNumber,RegAddress.CareOf,... 1 AVAILABLE LOCKSMITH LTD,05905727 NSPIRED LIMITED,06019953 CENTRE FOR COUNSELLING PSYCHOTHERAPY AND TRAINING LTD,07981734
Salut @ed Morton, merci pour la réponse! Je travaille sur un même big_file.csv à nouveau - active d'autres colonnes ont des virgules supplémentaires dans leurs chaînes - pas seulement "Nom d'entreprise". Existe-t-il un moyen d'effectuer cette opération sur toutes les colonnes de la CSV (Supprimer toutes les valeurs non alphanumériques dans les cordes de toutes les colonnes de la CSV)? Je viens de commencer à apprendre awk!
De rien. Mon script fait déjà ce que vous demandez dans votre commentaire, cela ne fait aucune hypothèse / restrictions à propos de tout domaine spécifique. L'avez-vous essayé?
Oh merci! J'essayais de l'analyser mentalement un peu. Je suppose que si je veux imprimer tous les cols et pas seulement les 2 premiers, je simples simplement remplacer impression 1 $, 2 $ code> avec
impression code> droite? :)
Droit. _____________
Basé sur les intrants de deux des réponses ci-dessous, j'ai essayé plusieurs approches: p>
SED -I '0, / CompanyNumber / S // CompanyNumber /' Big_File.csv Code> Li>
- Combinez des Xargs -L1 avec CSVCut et SED:
SED 'S /, \ / / G' BIG_FILE.CSV | xargs -l1 | CSVCT -C CompanyName, CompanyNumber> Big_File_Cleaned.csv code> Li>
ul> li>
ol>
Cela a fonctionné, mais était super lent. P>
-
une solution à Perl forte> de l'un des types de contributeurs!
- Première première ligne propre avec Perl:
perl -lne 'Si ($.> 1) {/^"(.+?)" "(.+?)/d; $ 1; $ $ y = 2 $; $ x = ~ s / [] // g; Imprimer "$ x, $ y"} else {print} 'big_file.csv> big_file_clean.csv code> li>
- puis filtrez uniquement les colonnes dont j'ai besoin:
CSVCT -C CompanyName, SociétéNumber BIG_FILE_CLEAN.CSV> BIG_FILE_CLEAN_NAMECODESONNY.CSV CODE> LI>
ul> li>
ol>
merci p>
Vous pouvez essayer avec cette SED:
sed -E ' :A s/^("[^,"]*),(.*)/\1\2/ # label A if CompanyName can have more than 1 comma tA s/"//g;s/([^,]*,[^,]*).*/\1/ ' big_file.csv
awk 'NR>1{gsub(/"/,"")sub(/.{4}$/,"")gsub(/!|,$/,"")sub(/, /," ")sub(/.{5}A/,"A")}1' file CompanyName, CompanyNumber,RegAddress.CareOf,... AVAILABLE LOCKSMITH LTD,05905727 NSPIRED LIMITED,06019953 CENTRE FOR COUNSELLING PSYCHAPY AND TRAINING LTD,07981734
Pourquoi garder la regadiste ... dans l'en-tête?
Pas besoin du tout!
Si vous avez une réponse de travail, mettez-la comme une réponse. Ne l'insérez pas dans la question!
Aaah! Oui désolé désolé!