Les Allergies
Alimentaires
Posez votre question Signaler

Specifier numéro du champ, command sed ou awk [Résolu]

teab - Dernière réponse le 6 mai 2010 à 19:37
Bonjour à tous,
Une petite question concernant la commande sed.
Voila mon problème. J'ai un fichier texte (toto.txt) qui contient 3 colonnes de nombres. Je dois remplacer à la ligne N (=15 par ex) le champ 3 par une chaine que je noterai newstr. Le champ 3 est une chaine que j'appelle oldstr.
fichier: str1 str2 oldstring
Jusqu'à présent, je faisais:
sed -i '15 s/oldstr/newstr/' toto.txt
resultat --> str1 str2 newstring
donc cela marche très bien sauf si le champ 2 a la même valeur que le champ 3:
fichier: str1 oldstr oldstr
Car dans ce cas il me remplace le champ 2.
Je sais qu'il existe de nombreuses solutions, mais j'en cherche une simple qui puisse alléger mon code; en indiquant juste le numéro du champ qui m'interesse (et que je connais a priori).
Merci d'avance!
teab
Lire la suite 

Specifier numéro du champ, command sed ou awk »

20 réponses
Réponse
+2
moins plus
Salut,

2 solutions. Si tu sais quelle occurrence remplacée, 1ère solution, si tu ne sais pas le nombre d'occurrences à l'avance, 2nd solution :

 jp@jp-kermic:~$ cat teab 
fichier: str1 str2 oldstr

fichier:str1 oldstr oldstr 

jp@jp-kermic:~$ sed 's/oldstr/newstr/2' teab 
fichier: str1 str2 oldstr

fichier:str1 oldstr newstr 

jp@jp-kermic:~$ sed 's/\(.*\)oldstr/\1newstr/' teab 
fichier: str1 str2 newstr

fichier:str1 oldstr newstr 

jp@jp-kermic:~$

;-))
teab - 5 mai 2010 à 09:33
Effectivement j'avais fait une erreur....donc ta méthode fonctionne.
Toutefois, elle me semble limitée. Je m'explique. Imaginons que j'ai en fait cette ligne:

4 olstr oldstr oldstr

Je veux cette fois remplacer uniquement le deuxième champ par newstr. C'est faisable avec la première méthode que tu avais proposé, mais cela m'oblige à rajouter une ligne de code en faisant une boucle conditionnelle. C'est pour ça que je cherchais une méthode qui me permettre de spécifier le numéro du champ et non de l'occurence.
Tu vois ce que je veux dire?
Si tu n'as pas mieux ce n'est pas grave, c'est déjà très bien!
jipicy- 5 mai 2010 à 10:16
Re-

une méthode qui me permettre de spécifier le numéro du champ et non de l'occurence.
Sed n'est pas fait pour ça ;-(
Sed est un éditeur de flux orienté ligne et non un éditeur de flux orienté champ. Pour ça il te faut te tourner vers "awk", qui lui est prévu pour traiter les "champs".
teab - 5 mai 2010 à 10:31
d'accord. C'est ce que j'avais commencé à faire, mais awk n'est pas facile à apprivoiser....
J'arrive à l'utiliser pour la lecture de fichier, mais pas pour le remplacement!
Ajouter un commentaire
Réponse
+0
moins plus
hello
pour change partiellement ou entèrement un champ spécifique avec awk
$ echo olstr oldstr oldstr oldstr | awk -v c=3 '{sub("old", "new", $c);print}'
olstr oldstr newstr oldstr
$ 
$ echo olstr oldstr oldstr oldstr | awk -v c=2 '{sub("old", "new", $c);print}'
olstr newstr oldstr oldstr
$  
$ echo olstr oldstr oldstr oldstr | awk -v c=2 '{$c="newstr";print}'
olstr newstr oldstr oldstr
$ 
$ echo olstr oldstr oldstr oldstr | awk -v c=4 '{$c="newstr";print}'
olstr oldstr oldstr newstr
$ 
teab - 6 mai 2010 à 13:00
Bonjour,

Alors j'ai testé ce matin. Effectivement il y un décalage de champ!
Le | devient le champ 5 au lieu de champ 4. Cependant je ne travaille pas sur les champs au delà du champ 3 donc cette méthode convient tout à fait!

Donc un grand merci à toi et aussi à Jipicy.

Pour ceux qui rencontreraient mon problème, je remets le code que tu as proposé:

sed -e 's/ /;/g' toto.txt |  awk -v c=4 'BEGIN{FS=OFS=";"} ; NR==4 {$c="newstr"}; {print}' |sed -e 's/;/ /g' 



J'ai une dernière question.
En fait la chaine 'newstr' est contenue dans un tableau tab, à la case i. La chaine est un nombre: 1.3333E+02 par exemple.


En reprenant ton code, il devient:

sed -e 's/ /;/g' toto.txt |  awk -v c=4 'BEGIN{FS=OFS=";"} ; NR==4 {$c='${tab[i]}'}; {print}' |sed -e 's/;/ /g' 


Le problème c'est que la valeur qui apparait dans le fichier n'est plus l'écriture scientifique mais l'écriture normale du nombre soit 133,33.

Y A t-il un moyen de le forcer à écrire la chaine exacte?
dubcek- 6 mai 2010 à 14:32
mettre des " pour que awk le traite comme une chaine de caractère et ne convertisse pas
...{$c="'${tab[i]}'"}; {....
teab - 6 mai 2010 à 19:37
Dubcek, un grand merci!
Tout fonctionne.

Bonne continuation!
teab
Ajouter un commentaire
Ce document intitulé « Specifier numéro du champ, command sed ou awk » issu de CommentCaMarche (www.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Dossier à la une
Passage au tout numérique : quel coût pour les particuliers ?