Je voudrais modifier le formatage de mon fichier en remplaçant l'espace contenu entre mes 3 champs par un ";" histoire de traiter ce fichier avec open office.
Le problème est que je ne peux lancer la commande tr -s " " ";" du fait des espaces contenus le 2ème champ.
Extrait du fichier:
562910 Services d'assainissement 1
562990 Tous les autres services de gestion des déchets 1
611420 Formation en informatique 6
...
J'aimerais avoir en sortie:
562910;Services d'assainissement;1
562990;Tous les autres services de gestion des déchets;1
611420;Formation en informatique;6
...
D'avance merci pour votre aide.
# man sed
Posté par doublehp (site web personnel) . Évalué à 1.
cat file | sed 's/\t/ /' > file-without-tabs
je te dirais bien
cat file | sed 's/ /;/' > file-without-tabs
mais si tu as deux espaces consecutifs, ca met deux ';'
je te propose donc:
cat file | sed 's/ / /' | sed 's/ / /' | sed 's/ / /' | sed 's/ / /' | sed 's/ / /' | sed 's/ / /' | sed 's/ / /' | sed 's/ / /' | sed 's/ /;/' > file-without-tabs
si tu as au plus 2^8 espaces consecutifs
je pense qu il existe une solution plus elegante a base de
sed 's/*{ }/ /'
ou truc du genre, mais si tu veux du vite fait, ca ira pour aujourd hui.
[^] # Re: man sed
Posté par doublehp (site web personnel) . Évalué à 1.
[^] # Re: man sed
Posté par doublehp (site web personnel) . Évalué à 1.
man awk, avec un for ... tu imprimes $1; puis tous les champs jusqu a l avant dernier
man sed: tu fais une substitution par le debut, et une par la fin: pour le premier, tu cherches un pattern suivi d un espace, mais n en contenant pas, et tu le substitues par le meme pattern suivi d un ';', et la meme chose a l envers par la fin.
Note que par default, une regexp commences toujours le matching par la fin.
[^] # Re: man sed
Posté par Eric Defour . Évalué à 2.
# En une ligne
Posté par Damien Pobel (site web personnel) . Évalué à 1.
cat file.txt | tr -s ' ' ';' | sed 's/\([a-zA-Z]\);\([a-zA-Z]\)/\1 \2/g'
Remplacer tous les espaces par des ; puis remplacement des ; entre deux lettres par un espaces...
https://damien.pobel.fr
[^] # Re: En une ligne
Posté par tgl . Évalué à 2.
sed -i 's:^\([0-9]*\) \(.*\) \([0-9]*\)$:$1;$2;$3:' fichier
Ou encore :sed -i 's| |;|;s|\(.*\) |$1;|' fichier
[^] # Re: En une ligne
Posté par tgl . Évalué à 4.
- le premier fait un remplacement de la ligne complète, dans laquelle 3 champs ont été identifiés avec des \(qqch\), par une ligne contenant ces 3 champs séparés par des ";" (c'est la partie "$1;$2;$3").
- le deuxième procède en deux étapes, deux commandes "s" séparées par un ";". La première commande remplace le 1er espace de la ligne (la commande "s" s'occupe uniquement de la première occurence trouvée quand on ne lui adjoint pas un "g" à la fin). La deuxième remplace uniquement le dernier espace de la ligne (c'est le "\(.*\)" de bourrage au début qui fait que c'est au dernier qu'on s'attaque, ce bourrage étant ensuite réintroduit dans la chaine de remplacement avec le "$1").
Bon y'a sûrement plus joli à faire, mais j'allais pas ouvrir la page info non plus...
[^] # Re: En une ligne
Posté par Eric Defour . Évalué à 1.
Je viens d'éxécuter ta commande avec des \1 \2 \3 à la place de $1 $2 $3 et ça fonctionne.
Merci à tous pour vos précieux conseils.
[^] # Re: En une ligne
Posté par tgl . Évalué à 2.
[^] # Re: En une ligne
Posté par tgl . Évalué à 3.
[^] # Re: En une ligne
Posté par Eric Defour . Évalué à 1.
811310;Réparation et entretien de machines et de matériel d'usage commercial et industriel;(sauf les véhicules automobiles et le matériel électronique);9
811420;Rembourrage et réparation de meubles;3
812320;Services de nettoyage à;sec et de blanchissage;(sauf le libre-service);1
812921;Laboratoires de développement et de tirage de photos;(sauf le service en une heure);1
813910;Associations de gens d'affaires;24
813920;Organisations professionnelles;6
Je viens de modifier la commande en rajoutant "\(" "," avec les lettres mais je n'arrive pas à exclure le "à" du problème d'affichage.
La solution est toute proche....
# Les regexps, ça roulaize !
Posté par Obsidian . Évalué à 3.
echo -e "12345 Service d assainissement 3" | sed -e "s/\(^[^\t ]*\)[\t ]\(..*\)[\t ]\([^\t ]*$\)/\1;\2;\3/g"
avec le lien qui va bien :
http://www.greenend.org.uk/rjk/2002/06/regexp.html(...)
Je t'invite quand même à essayer de décortiquer l'expression ci-dessus pour arriver à faire les tiennes.
Bon courage.
# une suggestion
Posté par fabien . Évalué à 2.
oui je sais qu'on peu le faire en SED, bon.... mais pourquoi ne pas utiliser un autre outil ?
Quand je vois la complexité et les effets de bords possible (dans certains cas ca ne marche pas en fonction de certains caractere... d'apres une des solution que j'ai lu : "à" ..) bref....
pourquoi ne pas faire un joli petit script en perl ou php.
moi je ne connais pas trop le perl, mais en php c'est relativement facile à faire : on lit la ligne, on la split, on prend le 1er item, on ajout le fameux ";" et on fusione les item suivant...
et encore là c'est pas ce qu'il y a de mieux , j'ai juset voulu faire rapide (2 a 3 ligne quoi) mais on peu "analyser la ligne" (ercherche le 1er espace quoi), pour descouper la ligne en deux et y mettre un ";" entre les deux....
enfin bref, c'est moins complexe, assez facile a maintenir et debugger.
je ne vois pas pourquoi s'en priver (oui ca fait un peu moins geek mais bon.. )
[^] # Re: une suggestion
Posté par doublehp (site web personnel) . Évalué à 2.
Quelque soit le langage, la logique de l operation est la meme, et sed est le langage qui permet de le faire le plus vite, meme si j en conviens un debutant comprendra plus vite le script php que sed.
en tant que Linuxien inveteres, nous nous devons de produire de la qualite. Et dans le cas present, la qualite maximale, c est sed. La preuve, une solution moins de 80 chars a ete proposee ici meme. Je te met au defi de le faire en moins de 80 char en php.
Tu comprendra toute l empleur de ce post si tu etudies un jour un langage non sequentiel comme le Prolog ou le VHDL.
[^] # Re: une suggestion
Posté par fabien . Évalué à 2.
juste deux remarquesn toutefois :
D'une part, l'avantage de php est de donner une solution pedagogique.
Avec le sed pondu ici ou là.. c'est pas evident, et je doute que le demandeur puisse reproduire la même chose.
avec le php, j'ai même pas eut besoin de donner le code, l'explication en bon francais se suffit a lui même
Deuxiement,
Plus performant ? oui, mais a quel prix ? (la taille du source n'est pas revelateur d'ailleur)
(il y a longtemps dans mes jeunes année) un jour un prof nous a fait plancher en TP sur la notion d'optimisation. pour nous montrer que le cout (comprendre la complexité) est exponentiel et qu'a un moment le gain est extrement faible.
En gros a "un certain stade" tu va galerer comme un malade pour optimiser (repenser tes structures, apprendre un nouveau langague..) pour gagner trois fois rien.
L'agorithme deviens inmaintenable, trop complexe...
la qualité de developpeur (selon lui) est de savoir ou s'arreter, non pas de pondre l'algo le + rapide.
ca se discute, mais c'est interressant, je garde cette reflexion en tête :)
en fait, j'avoue, j'aimerais bien être capable de pondre du sed comme voue le faites :)
[^] # Re: une suggestion
Posté par fabien . Évalué à 3.
bien sur ca depasse le 80 car :)
c'est facilement maintenable.
J'ai pas testé si l'espace est trouvé (pas de test non plus dans les exemple en sed) mais c'est facile, il suffit de balancer un if apres le strpos.
pour le nom du fichier, je l'ai mis en dur (comme les proposition sed hein) mais on peu le lire depuis la ligne de commande...
au moins un non-3l33t peut comprendre :)
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.