Je voudrais exécuter une recherche et un remplacement sur un fichier HTML via la ligne de commande.
Ma commande ressemble à ceci:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index.html
Lorsque je lance cela et regarde le fichier par la suite, il est vide. Il a supprimé le contenu de mon fichier.
Lorsque j'exécute ceci après avoir à nouveau restauré le fichier:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
C'est stdout
le contenu du fichier et la recherche et le remplacement ont été exécutés.
Pourquoi cela arrive-t-il?
shell
unix
sed
io-redirection
BBales
la source
la source
perl -pi -w -e 's/STRING_TO_REPLACE/REPLACE_WITH/g;' index.html
sed
commande beaucoup plus connexe pour trouver une chaîne et remplacer toute la ligne: stackoverflow.com/questions/11245144/…Réponses:
Lorsque le shell voit
> index.html
dans la ligne de commande, il ouvre le fichierindex.html
pour l' écriture , effaçant tout son contenu précédent.Pour résoudre ce problème, vous devez passer l'
-i
option poursed
effectuer les modifications en ligne et créer une sauvegarde du fichier d'origine avant d'effectuer les modifications sur place:Sans le .bak, la commande échouera sur certaines plates-formes, telles que Mac OSX.
la source
truncates the file
au lieu de leopens the file
rend probablement plus clair.sed -i '' 's/blah/xx/g'
.bak
aprèssed -i
?Un modèle alternatif utile est:
Cela a à peu près le même effet, sans utiliser l'
-i
option, et signifie en outre que, si le script sed échoue pour une raison quelconque, le fichier d'entrée n'est pas encombré. De plus, si la modification réussit, il ne reste aucun fichier de sauvegarde. Ce type d'idiome peut être utile dans les Makefiles.Beaucoup de graines ont l'
-i
option, mais pas toutes; le posix sed est celui qui ne fonctionne pas. Si vous visez la portabilité, il est donc préférable de l'éviter.la source
... && mv index.html{.tmp,}
sh
(si je me souviens bien) n'a pas cette{...}
extension. Dans un Makefile, vous utilisez peut-êtresh
plutôt quebash
, donc si vous visez la portabilité (ou la posixité), vous devrez éviter cette construction.Cela effectue une substitution globale sur place dans le fichier index.html. La citation de la chaîne évite les problèmes d'espaces dans la requête et le remplacement.
la source
utilisez l'option -i de sed, par exemple
la source
's/STRING_TO_REPLACE/REPLACE_WITH/g'
-i
effectue l'édition sur place des fichiers , il n'est donc pas logique de le combiner avec l' entrée stdin .Pour modifier plusieurs fichiers (et enregistrer une sauvegarde de chacun sous * .bak):
prendra tous les fichiers dans le répertoire et les remplacera
|
parx
ceci est appelé un "gâteau Perl" (facile comme un gâteau)la source
sed
comme exigence, il ne l'a utilisé que comme outil déjà essayé.Vous devriez essayer d'utiliser l'option
-i
de modification sur place.la source
Si vous avez un lien à ajouter, essayez ceci. Recherchez l'URL comme ci-dessus (en commençant par https et en terminant par.com ici) et remplacez-la par une chaîne d'URL. J'ai utilisé une variable
$pub_url
ici.s
signifie ici recherche etg
remplacement global.Ça marche !
la source
Attention: c'est une méthode dangereuse! Il abuse des tampons d'E / S sous Linux et avec des options spécifiques de mise en mémoire tampon, il parvient à travailler sur de petits fichiers. C'est une curiosité intéressante.Mais ne l'utilisez pas pour une situation réelle!
Outre l'
-i
option desed
vous pouvez utiliser l'tee
utilitaire .De
man
:Ainsi, la solution serait:
- ici le
tee
est répété pour s'assurer que le pipeline est tamponné. Ensuite, toutes les commandes du pipeline sont bloquées jusqu'à ce qu'elles obtiennent une entrée sur laquelle travailler. Chaque commande du pipeline démarre lorsque les commandes en amont ont écrit 1 tampon d'octets (la taille est définie quelque part ) à l'entrée de la commande. Donc, la dernière commandetee index.html
, qui ouvre le fichier pour l'écriture et le vide donc, s'exécute après la fin du pipeline en amont et la sortie est dans le tampon dans le pipeline.Les éléments suivants ne fonctionneront probablement pas:
- il exécutera les deux commandes du pipeline en même temps sans aucun blocage. (Sans bloquer, le pipeline doit passer les octets ligne par ligne au lieu de tampon par tampon. Comme lors de l'exécution
cat | sed s/bar/GGG/
. Sans blocage, il est plus interactif et généralement les pipelines de seulement 2 commandes s'exécutent sans mise en mémoire tampon et blocage. Les pipelines plus longs sont mis en mémoire tampon.) Latee index.html
volonté ouvrez le fichier pour l'écriture et il sera vidé. Cependant, si vous activez toujours la mise en mémoire tampon, la deuxième version fonctionnera également.la source
>
, mais le fait est que c'est une solution cassée qui est susceptible d'entraîner une perte de données).Le problème avec la commande
est-ce
file
le shell est tronqué avant que sed ne puisse réellement le traiter. En conséquence, vous obtenez un fichier vide.La méthode sed pour ce faire est d'utiliser
-i
pour éditer sur place, comme d'autres réponses l'ont suggéré. Cependant, ce n'est pas toujours ce que vous voulez.-i
créera un fichier temporaire qui sera ensuite utilisé pour remplacer le fichier d'origine. Cela pose problème si votre fichier d'origine était un lien (le lien sera remplacé par un fichier standard). Si vous devez conserver des liens, vous pouvez utiliser une variable temporaire pour stocker la sortie de sed avant de la réécrire dans le fichier, comme ceci:Mieux encore, utilisez
printf
plutôt queecho
puisqueecho
est susceptible de traiter\\
comme\
dans certains shells (par exemple, tiret):la source
sed 'code' file > file.tmp; cat file.tmp > file; rm file.tmp
Et la
ed
réponse:Pour réitérer ce codaddict répondu , les poignées de shell la redirection d' abord , effaçant le fichier « input.html », et puis le shell appelle la commande « sed » passer un fichier maintenant vide.
la source
ed
version" dessed
réponses? fonctionne-t-il plus rapidement?sed
ne mettent pas en œuvre la-i
modification sur place.ed
est omniprésent et vous permet d'enregistrer vos modifications dans le fichier d'origine. De plus, il est toujours bon d'avoir beaucoup d'outils dans votre kit.Vous pouvez utiliser Vim en mode Ex:
%
sélectionner toutes les lignesx
sauver et fermerla source
Je cherchais l'option où je peux définir la plage de lignes et j'ai trouvé la réponse. Par exemple, je veux changer host1 en host2 de la ligne 36-57.
Vous pouvez également utiliser l'option gi pour ignorer la casse des caractères.
la source
Avec tout le respect dû aux réponses correctes ci-dessus, c'est toujours une bonne idée de faire un "dry run" scripts comme ça, afin de ne pas corrompre votre fichier et de devoir recommencer à zéro.
Obtenez simplement votre script pour renverser la sortie sur la ligne de commande au lieu de l'écrire dans le fichier, par exemple, comme ça:
OU
De cette façon, vous pouvez voir et vérifier la sortie de la commande sans avoir à tronquer votre fichier.
la source