J'ai une exigence dans mon projet de remplacer du texte existant dans un fichier comme foo
par un autre texte comme fooofoo
:
abc.txt
name
foo
foo1
J'ai donc essayé:
sed -i "s/foo/fooofoo/g" abc.txt
Cependant, j'obtiens cette erreur:
sed: option illégale -
i
J'ai trouvé dans le manuel que je dois utiliser:
sed -i\ "s/foo/fooofoo/g" abc.txt
Cependant, cela ne fonctionne pas non plus.
J'ai trouvé des alternatives dans perl
et awk
aussi mais une solution dans Solaris sed
serait très appréciée.
J'utilise cette version de bash:
GNU bash, version 3.2.57 (1) -release (sparc-sun-solaris2.10)
text-processing
sed
solaris
tpsaitwal
la source
la source
/usr/gnu/bin/sed
support -i.Réponses:
Utilisez
ed
. Il est disponible sur la plupart des plates-formes et il peut modifier vos fichiers sur place.Depuis
sed
est basé sured
la syntaxe pour le remplacement des modèles est similaire:la source
ed
au lieu deex
, juste curieux? (Je sais que les deux sont conformes à POSIX et que j'ai lié aux spécifications.;))ex
? Pour répondre à votre question: puisque je ne l'utilise jamais,ex
je ne la connais pas. btw, j'ai vu des configurations oùed
était présent maisex
pas (mais pas l'inverse) ... le plus notable étant mon ordinateur portable :)ex
commandes. Toutes lesvi
commandes que vous pouvez taper qui commencent par deux points sont desex
commandes. Il y a bien sûr quelques extensions spécifiques à Vim, mais juste l'ensemble de commandes de base est incroyablement puissant et flexible et offre de nombreuses modifications par script.ex
et pourtant pased
.Si vous ne pouvez pas installer GNU sed, utilisez:
Cela utilise la redirection pour envoyer la sortie de sed vers un fichier temporaire. Si sed se termine avec succès, cela écrase
abc.txt
le fichier temporaire.Comme le montre le code source de GNU sed , c'est exactement ce qui
sed -i
fait. Donc, c'est à peu près aussi efficace quesed -i
.S'il
abc.tmp
existe déjà une chance , vous pouvez utilisermktemp
un utilitaire similaire pour générer le nom unique du temporaire.la source
ed
, car il lit tout le fichier en mémoire.Si vous voulez l'équivalent de
sed -i.bak
, c'est assez simple.Considérez ce script pour GNU sed:
Nous pouvons simplement remplacer la ligne marquée par
Cela déplace le fichier existant pour être une sauvegarde et écrit un nouveau fichier.
Si nous voulons l'équivalent de
alors c'est un peu plus complexe. Nous pouvons ouvrir le fichier pour le lire comme entrée standard, puis le dissocier, avant de diriger la sortie de sed pour le remplacer:
Nous le faisons dans un sous-shell, afin que notre stdin d'origine soit toujours disponible après cela. Il est possible de changer d'entrée et de revenir en arrière sans sous-coque, mais cette façon me semble plus claire.
Notez que nous prenons soin de copier d'abord, plutôt que de créer un nouveau
foo
fichier - cela est important si le fichier est connu sous plusieurs noms (c'est-à-dire avec des liens durs) et que vous voulez être sûr de ne pas rompre les liens .la source
Tout d'abord, vous devez savoir que la
i\
commande à laquelle vous faites référence consiste à insérer une ligne de texte, et non à sauvegarder le texte modifié dans le fichier. Il n'y a pas moyen spécifié Posix à utilisersed
pour cela.Ce que vous pouvez faire est d'utiliser
ex
, qui est spécifié par POSIX :La
x
commande est pour "enregistrer et quitter". Vous pouvez également utiliserwq
maisx
est plus court.Le
%
signe au début de la commande de remplacement signifie "Appliquer cette commande à chaque ligne du tampon". Vous pouvez1,$s/find/replace/g
également utiliser .Une différence majeure entre
ex
etsed
est qu'ilsed
s'agit d'un éditeur de flux . Il ne fonctionne que séquentiellement, ligne par ligne.ex
est beaucoup plus flexible que cela, et en fait, vous pouvez directement éditer des fichiers texte interactifsex
. Il est le prédécesseur immédiat devi
.la source
Utilisation
sed
et aucun fichier temporaire visible :Vous pouvez éviter de créer un "fichier temporaire" visible distinct :
Explication
Les systèmes Unix ne sont pas réellement supprimer le contenu du fichier à partir du disque jusqu'à ce qu'il soit à la fois dissociées dans le système de fichiers, et pas ouvert dans tout processus. Vous pouvez
exec 3<
donc ouvrir le fichier dans le shell pour lire sur le descripteur de fichier 3,rm
le fichier (qui le dissocie du système de fichiers), puis appelersed
avec le descripteur de fichier 3 utilisé comme entrée.Notez que cela est très différent de cela:
La différence est que lorsque vous le faites dans une seule commande, le shell ouvre simplement le même fichier pour la lecture et pour l'écriture avec l'option de tronquer le fichier - puisqu'il s'agit toujours du même fichier, vous perdez le contenu. Mais si vous l'ouvrez pour la lecture, alors
rm
, puis ouvrez le même chemin pour l'écriture, vous créez en fait un nouveau fichier au même chemin (mais à un nouvel inode et emplacement de disque, car l'original est toujours ouvert): donc le contenu est toujours disponible.Ensuite, une fois que vous avez terminé, vous pouvez fermer le descripteur de fichier que vous avez ouvert précédemment (c'est ce que fait la
exec 3<&-
syntaxe spéciale), qui libère le fichier d'origine afin que le système d'exploitation puisse supprimer (marquer comme inutilisé) son espace disque.Avertissements
Il y a quelques choses à garder à l'esprit à propos de cette solution:.
Vous n'obtenez qu'un seul "aller" à travers le contenu - il n'y a pas de moyen portable pour un shell de "rechercher" dans le descripteur de fichier - donc une fois qu'un programme lit une partie du contenu, d'autres programmes ne verront que le reste du fichier. Et
sed
lira l'intégralité du fichier.Il y a une petite chance que votre fichier d'origine soit perdu si votre shell / script / sed est tué avant la fin.
la source
perl -i
c'est une autre bonne option. La question demandait spécifiquement une solution compatible avec Solarissed
, contrairement aux solutions avecperl
etawk
qu'ils mentionnaient déjà. De plus, ma réponse visait principalement à ajouter quelque chose que je pensais utile de savoir et qui manquait dans les autres réponses.