Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 19/04/2012, à 10:04

buzut

Les bizareries de Sed [RÉSOLU]

Bonjour tout le monde

Voilà, j'expose mes tourments (puisque ce n'est pas un problème, juste un truc que je trouve bizare). Je rédigeais donc il y a quelque jours un petit mémo sur les commandes sed.

Dans le cas où l'on veut remplacer du texte dans plusieurs fichiers, on a plusieurs solutions, mais quand je fais :

for f in *.php; do cat $f|sed 's/test/reussi/' > $f; done

j'ai un fichier sur deux (à peu près) qui se retrouve vide…

En revanche, si je fais comme ça :

for f in *.php; do cat $f|sed 's/test/reussi/' > new/$f; done

c'est à dire sans "overwriter" les fichiers, mais en redirigeant la sortie vers un autre dossier, tout fonctionne à merveille…

Dans un cas encore plus similaire, ça marche aussi (sauf que ça sape la présentation) :

for f in *.php; do fn=`cat $f|sed 's/test/reussi/'`;  echo $fn > $f; done

Et sinon, si on veut faire les modifs directement dans les fichiers, je sais qu'il y a l'option -i. Mais vous l'aurez compris là n'est pas la question, j'aimerais juste comprendre le pourquoi du comment. C'est peut-être dû au fonctionnement interne de sed que j'ignore… Enfin si vous avez l'explication, je suis preneur smile

Merci d'avances de vos brillants éclaircissements

Dernière modification par buzut (Le 20/04/2013, à 16:57)

Hors ligne

#2 Le 19/04/2012, à 10:33

Postmortem

Re : Les bizareries de Sed [RÉSOLU]

Salut,
Ce fonctionnement est normal. Enfin, je ne sais pas si le mot normal est le bon mot à employer !

Tu travailles avec le même fichier en entrée et en sortie.
Les redirections étant effectuées avant l'exécution de la commande, le fichier résultat (qui est aussi celui d'origine) se retrouve vide.
Par contre, pourquoi une fois sur 2 ça semble bon, je ne sais pas trop.

Dans ta dernière commande, c'est le echo qui "mange" la mise en forme ; echo affiche tous les arguments qu'il reçoit séparés par une espace. Si tu mettais le echo comme ceci, la mise en forme serait gardée (sauf les lignes vides en fin de fichier qui sont "mangées" par la substitution de commande,  fn=`cat $f|sed 's/test/reussi/'` ) : echo "$fn" > $f

Ce ne sont donc pas des "bizareries" de sed, mais du shell.

Dernière modification par Postmortem (Le 19/04/2012, à 10:34)


Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#3 Le 19/04/2012, à 11:15

pingouinux

Re : Les bizareries de Sed [RÉSOLU]

Bonjour,
Pour info

cat $f|sed 's/test/reussi/'

est avantageusement remplacé par

sed 's/test/reussi/' "$f"

Les " " autour de $f sont utiles si le nom du fichier contient des espaces, et ne mangent pas de pain dans le cas contraire.

Hors ligne

#4 Le 19/04/2012, à 11:57

Bousky

Re : Les bizareries de Sed [RÉSOLU]

Pour utiliser sed « sur place » il faut utiliser l'option -i. De plus « cat <fichier> | … » c'est très moche, ça utilise des ressources inutilement alors que la plupart des commandes peuvent directement lire dans un fichier.

for f in *.php; do sed -i 's/test/reussi/' "$f" ; done

Regarde « man sed ».


Sinon dans le troisième exemple, c'est normal : il stocke d'abord le résultat de sed dans la variable, puis il ré-écrit le fichier. Par contre il faut mettre $fn entre guillemets doubles : "$fn".

Dernière modification par Bousky (Le 19/04/2012, à 11:59)


Linux qui plante complètement ? Plus rien ne répond ? On peut toujours le redémarrer proprement :
Alt + SysRq + REISUB (Retourne En Islande Sur Un Bateau !)

Hors ligne

#5 Le 19/04/2012, à 15:01

buzut

Re : Les bizareries de Sed [RÉSOLU]

@postmortem "Les redirections étant effectuées avant l'exécution de la commande, le fichier résultat (qui est aussi celui d'origine) se retrouve vide." je comprend pourquoi ça m'efface tout ! Merci.

@pingouinux & Bousky, je sais que la "cat | …" n'est pas très efficace ni la meilleur solution ! Bien que j'utilise la plupart du temps la syntaxe

sed 's/test/reussi/' "$f"

Je ne sais pas pourquoi, il m'arrive quand même de me servir du pipe… Mauvaise habitude !

Je remarque aussi en passant que l'option "-i" n'est pas forcement pratique sous mac puisque :

for f in *.php; do sed -i 's/test/reussi/' "$f" ; done
sed: 1: "test": undefined label 'est'
…

ne fonctionnera pas. Il faut adjoindre l'option -e et dans ce cas on a automatiquement une création de backup de la forme "$f"-e

Une autre bizarerie, du shell du mac cette fois-ci.

Merci en tout cas de vos réponses, vous avez éclairé ma lanterne.

Hors ligne