shell - sustituir - El comando sed buscar y reemplazar en archivo y sobrescribir archivo no funciona, vacĂa el archivo
sed sustituir caracteres especiales (13)
Con el debido respeto a las respuestas correctas anteriores, siempre es una buena idea "ejecutar en seco" scripts como esos, para que no dañe su archivo y tenga que comenzar de nuevo desde cero.
Simplemente haga que su script derrame el resultado a la línea de comandos en lugar de escribirlo en el archivo, por ejemplo, así:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
O
less index.html | sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g
De esta manera, puede ver y verificar la salida del comando sin que su archivo sea truncado.
Me gustaría ejecutar una búsqueda y reemplazo en un archivo HTML a través de la línea de comandos.
Mi orden se ve algo como esto:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index.html
Cuando ejecuto esto y miro el archivo después, está vacío. Se eliminó el contenido de mi archivo.
Cuando ejecuto esto después de restaurar el archivo de nuevo:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
El stdout
es el contenido del archivo y se ha ejecutado la búsqueda y reemplazo.
¿Por qué está pasando esto?
Cuando el shell ve > index.html
en la línea de comandos, abre el archivo index.html
para escribir , borrando todo su contenido anterior.
Para solucionar este problema, debe pasar la opción -i
a sed
para realizar los cambios en línea y crear una copia de seguridad del archivo original antes de que realice los cambios en el lugar:
sed -i.bak s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
Sin el .bak, el comando fallará en algunas plataformas, como Mac OSX.
Debería intentar usar la opción -i
para la edición en contexto.
El problema con el comando.
sed ''code'' file > file
es que el file
está truncado por el shell antes de que sed llegue a procesarlo. Como resultado, obtienes un archivo vacío.
La mejor manera de hacer esto es usar -i
para editar en su lugar, como sugieren otras respuestas. Sin embargo, esto no siempre es lo que quieres. -i
creará un archivo temporal que luego se usará para reemplazar el archivo original. Esto es problemático si su archivo original era un enlace (el enlace será reemplazado por un archivo normal). Si necesita conservar los enlaces, puede usar una variable temporal para almacenar la salida de sed antes de volver a escribirla en el archivo, como esto:
tmp=$(sed ''code'' file); echo -n "$tmp" > file
Mejor aún, use printf
lugar de echo
ya que es probable que echo
procese //
as /
en algunos shells (por ejemplo, dash):
tmp=$(sed ''code'' file); printf "%s" "$tmp" > file
Estaba buscando la opción donde puedo definir el rango de línea y encontré la respuesta. Por ejemplo, quiero cambiar host1 a host2 desde la línea 36-57.
sed ''36,57 s/host1/host2/g'' myfile.txt > myfile1.txt
Puedes usar la opción gi también para ignorar el caso del personaje.
sed ''30,40 s/version/story/gi'' myfile.txt > myfile1.txt
Para cambiar varios archivos (y guardar una copia de seguridad de cada uno como * .bak):
perl -p -i -e "s//|/x/g" *
tomará todos los archivos en el directorio y reemplazará |
con x
esto se llama un "pastel de Perl" (fácil como un pastel)
Puedes usar Vim en modo Ex:
ex -sc ''%s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g|x'' index.html
%
seleccionar todas las líneasx
guardar y cerrar
Un patrón alternativo, útil, es:
sed -e ''script script'' index.html > index.html.tmp && mv index.html.tmp index.html
Eso tiene el mismo efecto, sin usar la opción -i
, y además significa que, si la secuencia de comandos sed falla por alguna razón, el archivo de entrada no está saturado. Además, si la edición tiene éxito, no queda ningún archivo de copia de seguridad por ahí. Este tipo de idioma puede ser útil en Makefiles.
Bastantes seds tienen la opción -i
, pero no todas; el posix sed es uno que no lo hace. Si apuntas a la portabilidad, por lo tanto, es mejor evitarlo.
Y la respuesta ed
:
printf "%s/n" ''1,$s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g'' w q | ed index.html
Para reiterar a qué codaddict respondió , el shell controla primero la redirección, borrando el archivo "input.html", y luego el shell invoca el comando "sed" y le pasa un archivo ahora vacío.
use la opción sed -i, por ejemplo,
sed -i bak -e s/STRING_TO_REPLACE/REPLACE_WITH/g index.html
Advertencia: este es un método peligroso! Abusa de los buffers de entrada / salida en linux y con opciones específicas de almacenamiento en búfer, logra trabajar en archivos pequeños. Es una curiosidad interesante. ¡Pero no lo uses para una situación real!
Además de la opción -i
de sed
, puede utilizar la utilidad tee
.
Del man
:
tee - lee de la entrada estándar y escribe en la salida y archivos estándar
Entonces, la solución sería:
sed s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html | tee | tee index.html
- Aquí se repite el tee
para asegurarse de que la tubería está en búfer. Luego, todos los comandos en la canalización se bloquean hasta que obtienen información para trabajar. Cada comando en la tubería comienza cuando los comandos ascendentes han escrito 1 búfer de bytes (el tamaño está definido en somewhere ) en la entrada del comando. Por lo tanto, el último comando tee index.html
, que abre el archivo para escribirlo y, por lo tanto, lo vacía, se ejecuta después de que la canalización ascendente haya finalizado y la salida se encuentre en el búfer dentro de la tubería.
Lo más probable es que lo siguiente no funcione:
sed s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html | tee index.html
- ejecutará ambos comandos de la tubería al mismo tiempo sin ningún bloqueo. (Sin bloquear la tubería, debe pasar los bytes línea por línea en lugar de búfer por búfer. Igual que cuando ejecuta cat | sed s/bar/GGG/
. Sin bloqueo, es más interactivo y, por lo general, las tuberías de solo 2 comandos se ejecutan sin almacenamiento en búfer ni bloqueo . Las tuberías más largas se almacenan en búfer.) El tee index.html
abrirá el archivo para su escritura y se vaciará. Sin embargo, si activa el búfer siempre, la segunda versión también funcionará.
sed -i ''s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g'' index.html
Esto hace una sustitución global en el lugar en el archivo index.html. El citar la cadena evita problemas con espacios en blanco en la consulta y el reemplazo.
sed -i.bak "s#https.*/.com#$pub_url#g" MyHTMLFile.html
Si tiene un enlace para agregar, intente esto. Busque la URL como se indica arriba (comenzando con https y terminando con.com aquí) y sustitúyala por una cadena de URL. He utilizado una variable $pub_url
aquí. s
aquí significa búsqueda g
significa reemplazo global.
Funciona !