Bonjour,
J'ai besoin d'urgence de substituer dans un fichier des valeurs par d'autres présentes dans un autre fichier et je ne sait pas comment procéder.
N.B. Les 2 fichiers ont le même nombre de lignes (plusieurs centaines) et le champs1 (ville dans l'exemple) est dans le bon ordre dans le fichier2. Par contre il y a des trous dans la numérotation du fichier 1... Je précise aussi que je ne suis pas en bash 4 mais en 2.05b.0(1)-release
Exemple du fichier1 (contenant les infos à substituer) :
ville1 tata ville4 tbtb
ville3 ville5 tctc tdtd
ville4 tete ville1 tftf
ville5 tgtg thth ville3
Exemple du fichier2 (contenant les noms des villes) :
Lille
Paris
Lyon
Toulouse
Il me faut donc au final un fichier3 contenant :
Lille tata Lyon tbtb
Paris Toulouse tctc tdtd
Lyon tete Lille tftf
Toulouse tgtg thth Paris
Merci d'avance pour votre aide !
# join ?
Posté par nono14 (site web personnel) . Évalué à 2.
Tout est dans le titre.
Système - Réseau - Sécurité Open Source - Ouvert à de nouvelles opportunités
[^] # Re: join ?
Posté par fredlabidouille . Évalué à 0.
Peut être... je regarde le man de join et je tente... merci.
[^] # Re: join ?
Posté par fredlabidouille . Évalué à 0.
J'essaye de comprendre le fonctionnement de la commande join car j'obtiens ceci quand je la tente même en demandant de joindre les 2 fichiers sur le champ 1 :
join: fichier 2 n'est pas dans l'ordre attendu
join: fichier 1 n'est pas dans l'ordre attendu
Est-tu sur que cette commande est adaptée à ce que je souhaite faire ? Sachant que les 2 fichier n'ont pas de champs commun...
[^] # Re: join ?
Posté par fredlabidouille . Évalué à 0.
A présent j'en suis sur. Je ne peux pas faire cela avec join car il faut un champs commun dans les deux fichiers ce qui n'est pas mon cas...
[^] # Re: join ?
Posté par fredlabidouille . Évalué à 0.
De plus j'avais oublié que le champs1 pouvait se retrouver ailleurs dans le fichier1... désolé. Je mets à jour le post.
[^] # Re: join ?
Posté par Anthony Jaguenaud . Évalué à 1.
Grâce à toi, je lui ai trouvé une solution que j’espère il prendra le temps de comprendre.
Je suis content, je viens de découvrir join. C’est une bonne journée, j’ai appris un truc.
Par contre, je suis toujours pas au point avec cut, du coup, j’utilise awk :-p
En moins de 20 mns…
# explications ?
Posté par bertrand . Évalué à 1.
est ce que je comprend bien en disant que Adresse 1 correspond à la première ligne du fichier 2, adresse2 à la deuxième ...
Est ce qu'il y a des trous, par exemple pas d'adressse3 dans le premier fichier ?
Les fichiers sont ils gros ?
Solution proposé : charger en mémoire dans le variables adresse1,adresse2, adressen, les différentes lignes du fichier 2.
ensuite, boucle readline sur le premier fichier avec incrémentation d'un compteur de ligne, et echo de adresse${n} (utiliser expr) et de la suite de la ligne du premier fichier (on omet le premier champ).
S'il y a des trous, il faut rajouter des tests pour vérifier que l'on est bien en phase.
[^] # Re: explications ?
Posté par fredlabidouille . Évalué à 0.
Tout a fait. Entre temps j'ai changé adresse pas ville dans mon exemple mais c'est bien ça ville1 correspond bien à la première ligne du fichier2, adresse2 à le deuxième...
Non aucun trou.
Les fichiers font plusieurs centaines de lignes.
Trop de ligne pour gérer chaque ligne dans une variable je pense.
Je pense qu'il faut charger la première ligne du fichier2 (Paris), faire un sed avec substitution globale dans le fichier1 pour remplacer tout les ville1 par Paris, ensuite charger la seconde ligne du fichier2 et refaire un sed etc... mais j'ai du mal (je débute en scripting et j'ai du mal a imbriquer 2 boucles
# solution en bash
Posté par sputnick (site web personnel, Mastodon) . Évalué à 1.
Voici une solution à ton problème en bash (4) :
On ne peut pas mettre d'array dans le string...
[^] # Re: solution en bash
Posté par fredlabidouille . Évalué à 0.
Merci beaucoup pour ta proposition de solution mais le fichier des villes contenant plusieurs centaines de lignes ça vas pas être faisable comme ça je pense malheureusement. Il faut absolument que je lise les 2 fichiers et que je remplace toutes les occurrences comme par exemple ville1 par Lille, ville2 par Paris etc...
[^] # Re: solution en bash
Posté par NeoX . Évalué à 2.
pourquoi ça ne passerais pas ?
il lit bien tous le fichier A (et compte le nombre de ligne, range les villes dans un tableau)
puis lis le fichier 2 pour traiter ligne par ligne et remplacer ville1 par paris, ville2 par lyon...
[^] # Re: solution en bash
Posté par fredlabidouille . Évalué à 0.
J'ai du mal à comprendre ta premiere ligne :
ville=( "" Lille Paris Lyon Toulouse )
Ca met juste dans la variable les 4 premieres valeurs du fichier mais ça ne lis pas tous le fichier.
[^] # Re: solution en bash
Posté par NeoX . Évalué à 2.
parce qu'il ne va pas te donner la réponse à ton exercice
il faut que tu cherches un peu,
que tu comprennes quelle commande fait quoi
et que tu adaptes les idées qu'on te balance.
;)
# typo :°
Posté par sputnick (site web personnel, Mastodon) . Évalué à 0.
Apparemment on peut pas éditer : il faut mettre dans la boucle for count+1 pour gérer Toulouse ;)
On ne peut pas mettre d'array dans le string...
[^] # Re: typo :°
Posté par fredlabidouille . Évalué à 0.
Comme dit au dessus mes fichiers font plusieurs centaines de lignes... ça ne passera donc pas avec ta solution il me semble malheureusement.
# si si, c'est jouable :
Posté par sputnick (site web personnel, Mastodon) . Évalué à 0.
Suffit de récupérer le deuxième fichier dans un tableau :
On ne peut pas mettre d'array dans le string...
[^] # Re: si si, c'est jouable :
Posté par sputnick (site web personnel, Mastodon) . Évalué à -1.
Ce qui donnes au final :
On ne peut pas mettre d'array dans le string...
[^] # Re: si si, c'est jouable :
Posté par sputnick (site web personnel, Mastodon) . Évalué à 1.
Une autre solution :
On ne peut pas mettre d'array dans le string...
[^] # Re: si si, c'est jouable :
Posté par JGO . Évalué à 0.
[^] # ouch
Posté par sputnick (site web personnel, Mastodon) . Évalué à 0.
Erreurs :
On ne peut pas mettre d'array dans le string...
[^] # Re: ouch
Posté par JGO . Évalué à 2.
Je cherche pas à donner une solution parfaite, je donne une des directions possibles, qui n'est juste pas totalement peaufinée. Perso je n'ai pas compris grand chose aux autres solutions proposées, et je vois pas pourquoi on serait obligé de répondre avec des tableaux bidimensionnels, des while ou des for si on sait faire autrement. There's more than one way to do it.
[^] # Re: ouch
Posté par NeoX . Évalué à 3.
ou simplement faire un seq $count 1 -1
pour compter de $count jusqu'à 1 avec un pas de -1 (donc compter à l'envers
# sed quand même
Posté par gaaaaaAab . Évalué à 2.
j'arrive un peu après la bataille, mais, en tenant compte des deux premières remarques de sputnick:
[^] # Re: sed quand même
Posté par fredlabidouille . Évalué à 0.
MErci mais en fait j'ai de trous dans le numérotation donc ça n e fonctionne pas encore... je modifie à nouveau mon post de départ. Désolé.
# Plus simple :
Posté par sputnick (site web personnel, Mastodon) . Évalué à 0.
On ne peut pas mettre d'array dans le string...
[^] # Re: Plus simple :
Posté par fredlabidouille . Évalué à 0.
Merci mais en fait j'ai des trous dans la numérotation ce qui fait qu'il y a un décalage à partir de la... je cherche un méthode pour vraiement récupérer les infos ligne par ligne. exemple si par exemple il n'y a pas de ville2: ville1 -> Lille ville3 -> Paris etc... si vous voyez comment faire je suis preneur.
[^] # Re: Plus simple :
Posté par fearan . Évalué à 2.
un bête
(( c++ )
until grep -sqw ville$c
do
((c++))
done
permet de s'assurer de l'existence de la présence de la ville ;)
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
# petit cours d'algorithme (algorythmique)
Posté par NeoX . Évalué à 2.
quand on fait de la programmation, on oublie souvent de réfléchir en français, et en décortiquant le problème étape par étape.
les programmeurs habitués et rodés à l'exercice font les deux en meme temps, mais parfois cela ne fonctionne pas.
et pour les débutants, autant faire les choses bien.
Alors commence par réfléchir à ton problème en français :
j'ai un deuxième fichier (B) contenant des données, présentée en ligne, présentant la correspondance ville1 -> paris, ville2 -> reims ...
ce que je veux : remplacer dans le premier fichier, les mots ville1 par Paris, ville2 par Reims, etc (tel que définis dans le fichier B).
La premiere chose qui vient à l'esprit simplement, c'est :
1°) lire une ligne dans le fichier B,
2°) pour chaque ligne sortir le motif cherché "ville1" et le motif de remplacement 'Paris'
3°) effectuer le remplacement dans FichierA avec le motif recherché/remplacé définit en 2°)
4°) recommencer en 1°) avec la ligne suivante
ce qui se traduit en algorithme suivant :
tant qu'il y a des lignes dans fichierB
lire une ligne
extraire le motif de recherche
extraire le motif de remplacement
faire le rechercher/remplacer dans fichierA
passer à la ligne suivante
en général une fois l'algorithme posé, l'écrire dans du code n'est plus qu'une histoire de traduction.
en perl :
en bash
# ZSH encore vainqueur par KO!
Posté par calandoa . Évalué à 3.
En 5 lignes, sans aucune commande externe:
Avant de passer aux explications, ouvrez votre fenêtre et criez « Gloire à Zsh » 5 fois à la cantonade.
On part du principe que
v
etd
font la même longueur, et que le premier mot de chaque ligne ded
est unique.Dans le tableau
v
, on met le fichier en argument 1 contenant le nom des ville (1 élément = 1 ville).Dans le tableau
d
, on met le fichier en argument 2 avec les infos à substituer (1 élément = 1 ligne).Puis, pour chaque ligne n de
d
, on remplace le premier mot de cette ligne par la n-ième ville (avec le remplacement qui s'applique sur la totalité ded
).Enfin on affiche
d
en sautant une ligne à chaque élément.Bien entendu, je viens de pondre ce script du premier coup, et je ne l'ai même pas vérifié tellement il est évident qu'il marche... Que je sois foudroyé si je m
# Résolu
Posté par fredlabidouille . Évalué à 0.
Bonjour,
Le problème à été résolu de la manière suivante :
i=1
while read line
do
valeur=$(sed -n "${i}p" fichier2)
sed -i "s/${line%% *}/${valeur}/Ig" fichier1
((i++))
done < fichier1
N.B. : La solution n'est pas de moi mais d'une personne d'un autre forum
Merci à tous pour votre aide et vos conseils.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.