Shell unix : Remplacement de valeurs à partir d'un fichier

Résolu/Fermé
agobats Messages postés 17 Date d'inscription dimanche 20 juillet 2014 Statut Membre Dernière intervention 17 septembre 2015 - Modifié par agobats le 13/09/2015 à 17:45
dna.factory Messages postés 24938 Date d'inscription mercredi 18 avril 2007 Statut Modérateur Dernière intervention 18 avril 2024 - 5 févr. 2016 à 11:13
Bonjour,

je voudrais, à partir d'unix, procéder à un remplacement de valeurs de texte à partir d'une table de correspondance.
Je m'explique : j'ai donc une table de correspondance appelée table.txt qui contient 2 colonnes, la première contient l'ancienne valeur et la deuxième la nouvelle valeur.
A partir de cette table je veux remplacer dans un fichier file.out les anciennes valeurs par les nouvelles.

table.txt :
orange pomme
banane kiwi
fraise framboise
peche abricot
...

file.out :
peche France
orange Maroc
peche Nouvelle-Zelande
fraise Espagne

Merci beaucoup de votre aide.

A voir également:

3 réponses

zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 407
13 sept. 2015 à 23:30
$ cat table 
orange pomme
banane kiwi
fraise framboise
peche abricot

$ cat out
peche France
orange Maroc
peche Nouvelle-Zelande
fraise Espagne

$ join -1 1 -2 1 -o 1.2 2.2 <(sort table) <(sort out)
framboise Espagne
pomme Maroc
abricot France
abricot Nouvelle-Zelande

1
agobats Messages postés 17 Date d'inscription dimanche 20 juillet 2014 Statut Membre Dernière intervention 17 septembre 2015
14 sept. 2015 à 00:47
Mon exemple n'était pas bon car le fichier final n'est pas forcément sur 2 colonnes. le texte à remplacer peut se retrouver 2 fois dans une même ligne à des emplacements différents.
De plus je ne dois surtout pas trier les données

Désolé de ne pas avoir été suffisamment précis dans mon exemple. J'aurai dû te joindre les fichiers mais comme je ne les avais pas avec moi.

Ceci dit la commande join pourra me servir pour une autre application.

Salutations.
0
agobats Messages postés 17 Date d'inscription dimanche 20 juillet 2014 Statut Membre Dernière intervention 17 septembre 2015 > agobats Messages postés 17 Date d'inscription dimanche 20 juillet 2014 Statut Membre Dernière intervention 17 septembre 2015
Modifié par agobats le 14/09/2015 à 20:28
Bonjour,

Cette-fois-ci je joins un extrait des fichiers. Après vérification, je me suis trompé sur la position du texte à remplacer. Le fichier a toujours ce format et la valeur a changer est toujours au même endroit (avant-denier caractère) et n'apparaît qu'une fois par ligne. Je ne trouve pas la solution, je pensais qu'avec une commande sed et éventuellement un cut ça serait possible, mais comme je suis un peu néophyte sur les boucles.
Fichier d'entrée :
K 1000. 1000.
9 2880. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='3'
9 2880. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='3'
9 2255. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='5'
9 4460. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='3'
9 3200. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='3'
9 3040. 2925.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='5'
9 3040. 2270.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='5'
9 3040. 2630.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='5'
9 3040. 2780.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='3'
9 3040. 1440.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='3'
9 3210. 1380.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='5'
9 4460. 1380.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='1'

Table :
1 (A12)
2 (A13)
3 (A15)
4 (A16)
5 (A17)

Fichier résultat :

K 1000. 1000.
9 2880. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 2880. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 2255. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 4460. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3200. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3040. 2925.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 3040. 2270.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 3040. 2630.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 3040. 2780.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3040. 1440.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3210. 1380.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 4460. 1380.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A12)'

Merci pour votre aide.
0
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
Modifié par dubcek le 15/09/2015 à 09:04
hello
$ awk -F "[ ']" '/[(]/  {t[$1]=$2; next} /=/ {$5=t[$5] "'\''"; sub("= ", "='\''")} {print}' table fichier
K 1000. 1000.
9 2880. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 2880. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 2255. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 4460. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3200. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3040. 2925.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 3040. 2270.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 3040. 2630.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 3040. 2780.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3040. 1440.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3210. 1380.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 4460. 1380.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A12)'
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 407 > dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024
15 sept. 2015 à 09:53
Salut,

awk c'est quand même puissant ;-))

Bon je mets quand même ma solution (bash + sed) ;-))

$ cat table 
1 (A12)
2 (A13)
3 (A15)
4 (A16)
5 (A17)

$ cat fich
K 1000. 1000.
9 2880. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='3'
9 2880. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='3'
9 2255. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='5'
9 4460. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='3'
9 3200. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='3'
9 3040. 2925.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='5'
9 3040. 2270.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='5'
9 3040. 2630.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='5'
9 3040. 2780.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='3'
9 3040. 1440.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='3'
9 3210. 1380.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='5'
9 4460. 1380.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='1'

$ cat foo.sh
#!/bin/bash

while read line
do
sed -i "/^ATTRIBUT/{s/='${line% *}'/='${line#* }'/}" fich
done < table

$ ./foo.sh

$ cat fich
K 1000. 1000.
9 2880. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 2880. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 2255. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 4460. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3200. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3040. 2925.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 3040. 2270.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 3040. 2630.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 3040. 2780.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3040. 1440.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3210. 1380.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 4460. 1380.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A12)'
0
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
Modifié par dubcek le 15/09/2015 à 11:27
et aussi
$  sed "s+^+s/'+; s+ +'$/'+;s+)+)'/+"  table| sed -f - fichier
K 1000. 1000.
9 2880. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 2880. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 2255. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 4460. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3200. 3040.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3040. 2925.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 3040. 2270.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 3040. 2630.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 3040. 2780.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3040. 1440.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A15)'
9 3210. 1380.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A17)'
9 4460. 1380.
ATTRIBUT CHANGE NAME=MATERIAL VALUE='(A12)'
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 407
13 sept. 2015 à 19:41
Salut,

Pas sûr d'avoir tout pigé ;-(

Et le fichier final doit ressembler à ???
0
agobats Messages postés 17 Date d'inscription dimanche 20 juillet 2014 Statut Membre Dernière intervention 17 septembre 2015
13 sept. 2015 à 23:08
Salut,
Le fichier final doit ressembler à cela :

abricot France
pomme Maroc
abricot Nouvelle-Zelande
framboise Espagne

Merci d'avoir jeté un oeil déjà. ;-(
0
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
16 sept. 2015 à 08:18
sur Solaris, utiliser nawk à la place de awk
0
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
Modifié par dubcek le 16/09/2015 à 10:31
ce code ne passe pas sur Solaris ?
sed "s+^+s/'+; s+ +'$/'+;s+)+)'/+"  table| sed -f - fichier

essayer
sed -e "s+^+s/'+" -e "s+ +'$/'+" -e "s+)+)'/+"  table| sed -f - fichier
0
agobats Messages postés 17 Date d'inscription dimanche 20 juillet 2014 Statut Membre Dernière intervention 17 septembre 2015
16 sept. 2015 à 13:52
Bonjour,
Avec la commande nawk ça ne passe pas j'ai le message suivant :
nawk : syntax error at source line
context is '/[(]/ {t[$1]=$2; next} >>> /= <<<
nawk: bailing out at source line 1
Avec les commande sed, j'ai le message :
Cannont open pathern-file
Désolé pour le dérangement. Ne serait-il pas possible de passer par une commande plus simple du genre :
on déclare les 2 valeurs, puis dans une boucle on insére la commande suivante :
sed 's/$val1/$val2/g' <file.input >file.out

Salutations.
0
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
Modifié par dubcek le 16/09/2015 à 14:38
essayer sed en 2 étapes
sed -e "s+^+s/'+" -e "s+ +'$/'+" -e "s+)+)'/+"  table > cmd.sed
sed -f cmd.sed fichier
et
$ cat code.awk
/[(]/ {t[$1]=$2; next}; /=/ {split($0, a, "'"); sub("'" "[0-9]+", "'" t[a[2]])}; {print}
$ nawk -f code.awk table fichier
0
agobats Messages postés 17 Date d'inscription dimanche 20 juillet 2014 Statut Membre Dernière intervention 17 septembre 2015
Modifié par agobats le 16/09/2015 à 16:59
sur la cammande awk, j'ai le message suivant :
ksh: syntax error: '(' unexpected
Pour la commande sed c'est nettement mieux sauf que le fichier n'est pas mis à jour. J'ai aussi supprimé le $, car avec rien se se passait. Par contre je voudrais que le fichier soit sauvegardé et pas seulement affcihé.
Merci pour tout
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 407 > agobats Messages postés 17 Date d'inscription dimanche 20 juillet 2014 Statut Membre Dernière intervention 17 septembre 2015
16 sept. 2015 à 16:38
Pour la commande sed c'est nettement mieux sauf que le fichier n'est pas mis à jour complétement.
Pas complètement n'est pas une réponse pouvant nous mettre sur la voie ;-(
Peux-tu développer s'il te plaît ?

J'ai supprimé le $, car avec rien se se passait
T'es sûr ? ;-\
Le caractère $ représente la fin de ligne et rien d'autre.

Par contre je voudrais que le fichier soit sauvegardé et pas seulement affcihé.
Suffit de faire une redirection
sed -f cmd.sed fichier > fich.final
0