2009-04-06 6 views

Répondre

16
$ sed -i -e's/SO/so/' so/app.yaml 

Les -i moyens en place.

+0

À partir de la page de manuel: Il est déconseillé de donner une extension de longueur nulle lorsque vous modifiez des fichiers sur place, car vous risquez d'être corrompu ou partiellement contenu dans des situations où l'espace disque est épuisé, etc .. – Kaarel

+0

J'ai lutté avec cela pendant les trente dernières minutes. – nlucaroni

+1

Au cas où cela ne fonctionnerait pas pour vous: la version de 'sed' que vous utilisez ne supporte probablement pas' -i' - par exemple, dans Solaris. Souvent, là où c'est le cas, il y aura un 'gsed' quelque part qui le supporte. –

3

Je crois que rediriger la sortie dans le même fichier que celui que vous êtes en train d'éditer est à l'origine de votre problème.

Vous avez besoin de rediriger la sortie standard vers un fichier temporaire et lorsque sed est effectué remplacer le fichier original par le fichier temporaire.

+0

Comment pouvez-vous faire cela en tant que doublure sans laisser de fichiers fictifs dans le dossier? –

+1

Eh bien, le dossier "/ tmp" est pour les fichiers factices. Donc ça pourrait être quelque chose comme ça: sed s/SO/so/app.yaml>/tmp/tmp321; mv -f/tmp/tmp321 so/app.yaml – posila

5

Le > utilisé dans la tuyauterie ouvre le fichier de sortie lorsque les canaux sont tous configurés, c'est-à-dire avant l'exécution de la commande. Ainsi, le fichier d'entrée est tronqué avant l'exécution de sed. C'est un problème avec toutes les redirections de shell, pas seulement avec sed.

La réponse de Sheldon Young montre comment utiliser l'édition sur place.

+0

Il semble que le chemin de Young soit le seul. J'ai essayé le code suivant aussi sans succès 'sed s/ABC/abc/settings.py'> settings.py. –

+0

Je pense que l'utilisation de '>' que @Rob suggère est de le sortir dans un fichier tmp, puis de le recopier. 'sed s/ABC/abc/settings.py> tmp; cp tmp settings.py' –

5

Vous utilisez le mauvais outil pour le travail. sed est un flux éditeur (c'est pourquoi il est appelé sed), donc c'est pour l'édition en vol de flux dans un tuyau. ed OTOH est un éditeur de fichier, qui peut faire tout ce que sed peut faire, sauf qu'il fonctionne sur les fichiers au lieu des flux. (En fait, il est l'inverse. ed est l'utilitaire original et sed est un clone qui évite d'avoir à créer des fichiers temporaires pour les flux)

ed fonctionne comme sed (parce que sed est juste un clone), mais avec une différence importante: vous pouvez vous déplacer dans les fichiers, mais vous ne pouvez pas vous déplacer dans les flux. Ainsi, toutes les commandes dans ed prennent un paramètre d'adresse qui indique ed, dans le fichier pour appliquer la commande. Dans votre cas, vous voulez appliquer la commande partout dans le fichier, de sorte que le paramètre d'adresse est juste , parce que a,b signifie « de la ligne a à la ligne b » et la valeur par défaut pour a est 1 (début de fichier) et La valeur par défaut pour b est $ (fin de fichier), donc les laisser tous les deux signifie "du début du fichier à la fin du fichier". Puis vient le s (pour le remplacement) et le reste ressemble beaucoup à sed. Par conséquent, votre commande seds/SO/so/ se transforme en commande ,s/SO/so/.

Et, encore une fois parce que ed est un éditeur de fichiers, et plus précisément, un éditeur de fichiers interactif, nous avons aussi besoin d'écrire (w) le fichier et quittez (q) l'éditeur.

C'est à quoi il ressemble dans son intégralité:

ed -- so/app.yaml <<-HERE 
    ,s/SO/so/ 
    w 
    q 
HERE 

Voir aussi my answer à une question similaire. Ce qui se passe dans votre cas, c'est que l'exécution d'un pipeline est un processus en deux étapes: construisez d'abord le pipeline, puis exécutez-le. > signifie "ouvrir le fichier, tronquer il, et le connecter au filedescriptor 1 (stdout)". Alors seulement est le canal réellement exécuté, c'est-à-dire que sed est exécuté, mais à ce moment, le fichier a déjà été tronqué.

Certaines versions de sed ont également un paramètre pour -i en place l'édition des fichiers, qui fait sed se comporter un peu plus comme ed, mais en utilisant ce n'est pas conseillé:, il ne abord supporte pas toutes les fonctionnalités de ed, mais plus important encore, il s'agit d'une extension propriétaire non standard de GNU sed qui ne fonctionne pas sur de nombreux systèmes non-GNU. Cela fait un moment que j'ai utilisé un système non-GNU, mais en dernier j'ai utilisé un, ni Solaris ni OpenBSD ni HP-UX ni IBM AIX sed supporté le paramètre -i.

+0

"extension propriétaire de GNU sed" @ Jörg: Voulez-vous dire que GNU gagne de l'argent en vendant leurs codes? J'ai toujours eu l'idée que n'importe qui peut utiliser gratuitement le logiciel GNU qui suit la licence GNU (c'est-à-dire que vous devez publier votre code gratuitement pour les autres si vous utilisez le code GNU). –

+0

Ce n'est pas ce que je voulais dire. L'anglais n'est pas ma langue maternelle, peut-être que «propriétaire» est le mauvais mot. Je veux dire que '-i' n'est disponible que dans GNU sed, et ne fait pas partie du standard POSIX/SUS, donc GNU peut redéfinir '-i' comme bon lui semble, d'autres fournisseurs peuvent implémenter '-i' * want ... –

+0

... ou ne pas l'implémenter du tout. Et il n'y a pas de définition de ce que '-i' signifie, sauf le code source de GNU sed. Mon université avait l'habitude d'utiliser HP-UX sur leurs serveurs, et le problème # 1 pour les étudiants était qu'ils essayaient d'utiliser des choses comme 'sed -i' ou 'bash' ou tout ce qu'ils savaient de leur ... –

Questions connexes