Dans un fichier texte, je veux supprimer ,
(virgules) et aussi les "
(guillemets) (uniquement si les guillemets doubles contiennent des nombres séparés par des virgules).
56,72,"12,34,54",x,y,"foo,a,b,bar"
Sortie attendue
56,72,123454,x,y,"foo,a,b,bar"
Remarque: je montre la ligne ci-dessus à titre d'exemple. Mon fichier texte contient de nombreuses lignes comme ci-dessus et les nombres séparés par des virgules présents dans les guillemets doubles doivent varier. C'est,
56,72,"12,34,54",x,y,"foo,a,b,bar"
56,92,"12,34",x,y,"foo,a,b,bar"
56,72,"12,34,54,78,76,54,67",x,y,"foo,a,b,bar"
56,72,x,y,"foo,a,b,bar","12,34,54"
56,72,x,y,"foo,a,b,bar","12,34,54","45,57,84,92","bar,foo"
Production attendue:
56,72,123454,x,y,"foo,a,b,bar"
56,92,1234,x,y,"foo,a,b,bar"
56,72,12345478765467,x,y,"foo,a,b,bar"
56,72,x,y,"foo,a,b,bar",123454
56,72,x,y,"foo,a,b,bar",123454,45578492,"bar,foo"
Il y a un n
certain nombre de nombres dans les guillemets séparés par des virgules. Et laissez également les guillemets doubles qui contiennent les caractères tels quels.
J'adore l' sed
outil de traitement de texte. Je suis heureux si vous postez une sed
solution pour cela.
text-processing
sed
csv
Avinash Raj
la source
la source
56,72,"12,34,54",x,y,"foo,a,b,bar"
à56,72,123454,x,y,"a,b"
,foo
etbar
disparaît. Est-ce la sortie souhaitée?foo
etbar
) sont supprimés avec les virgules. De plus, certaines des citations disparaissent là où d'autres restent. Sans oublier que les virgules entrea
etb
restent aussi. Y a-t-il une tendance à cela?Réponses:
Ceci (adapté d' ici ) devrait faire ce dont vous avez besoin, bien que celui de @ rici Perl soit beaucoup plus simple:
Explication
:a
: définir une étiquette appeléea
.s/(("[0-9,]*",?)*"[0-9,]*),/\1/
: Celui-ci doit être décomposé(foo(bar))
,\1
serafoobar
et\2
serabar
."[0-9,]*",?
: correspond à 0 ou plus de0-9
ou,
, suivi de 0 ou 1,
.("[0-9,]*",?)*
: correspond à 0 ou plus de ce qui précède."[0-9,]*
: correspond à 0 ou plus0-9
ou,
juste après un"
ta;
: revenir à l'étiquettea
et recommencer si la substitution a réussi.s/""/","/g;
: post-traitement. Remplacez""
par","
.s/"([0-9]*)",?/\1,/g
: supprime toutes les citations autour des nombres.Cela pourrait être plus facile à comprendre avec un autre exemple:
Ainsi, bien que vous puissiez trouver un numéro juste après un devis et suivi d'une virgule et d'un autre numéro, joignez les deux chiffres ensemble et répétez le processus jusqu'à ce qu'il ne soit plus possible.
À ce stade, je pense qu'il est utile de mentionner une citation
info sed
qui apparaît dans la section décrivant les fonctions avancées telles que l'étiquette utilisée ci-dessus (merci d'avoir trouvé si @Braiam):la source
Si perl est OK, voici une manière courte (et probablement rapide, sinon nécessairement simple :)):
Le
e
drapeau de l's:::
opérateur (qui n'est qu'une autre façon d'écrires///
) fait que le remplacement est traité comme une expression qui est évaluée à chaque fois. Cette expression prend la$1
capture de l'expression régulière (qui manque déjà les guillemets) et la traduit (y///
, qui peut également s'écriretr///
) en supprimant (/d
) toutes les virgules. L'r
indicateur toy
est nécessaire pour que la valeur soit la chaîne traduite, au lieu du nombre de traductions.Pour ceux qui se sentent en quelque sorte souillés par perl, voici l'équivalent python. Python n'est vraiment pas un outil shell one-liner, mais parfois il peut être cajolé en coopération. Les éléments suivants peuvent être écrits sur une seule ligne (contrairement aux
for
boucles, qui ne peuvent pas l'être), mais le défilement horizontal la rend (encore plus) illisible:la source
y///
au lieu detr///
nous sauver un caractère de plus.Pour les données CSV, j'utiliserais un langage avec un véritable analyseur CSV. Par exemple avec Ruby:
la source
Salut Voici le code Python pour remplacer les virgules par des guillemets doubles, les virgules sont remplacées par le caractère pipe (|)
Ce code Python remplace les virgules entre guillemets
par exemple: x, y, z, 1,2, "r, e, t, y", h, 8,5,6
si remplacer par Tuyau x, y, z, 1,2, "r | e | t | y", h, 8,5,6
si remplacer par null x, y, z, 1,2, "rety", h, 8,5,6
la source