Me gustaría ejecutar una búsqueda y reemplazo en un archivo HTML a través de la línea de comando.
Mi comando se parece a 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 nuevamente:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
El stdout
es el contenido del archivo, y la búsqueda y reemplazo se ha ejecutado.
¿Por qué está pasando esto?
shell
unix
sed
io-redirection
BBales
fuente
fuente
perl -pi -w -e 's/STRING_TO_REPLACE/REPLACE_WITH/g;' index.html
sed
comando muy relacionado para encontrar una cadena y reemplazar toda la línea: stackoverflow.com/questions/11245144/…Respuestas:
Cuando el shell ve
> index.html
en la línea de comando, abre el archivoindex.html
para escribir , borrando todo su contenido anterior.Para solucionar esto, debe pasar la
-i
opción desed
realizar los cambios en línea y crear una copia de seguridad del archivo original antes de que los cambios se realicen en el lugar:Sin el .bak, el comando fallará en algunas plataformas, como Mac OSX.
fuente
truncates the file
lugar deopens the file
probablemente lo aclara.sed -i '' 's/blah/xx/g'
.bak
despuéssed -i
?Un patrón alternativo y útil es:
Eso tiene el mismo efecto, sin usar la
-i
opción, y además significa que, si la secuencia de comandos sed falla por alguna razón, el archivo de entrada no está bloqueado. Además, si la edición es exitosa, no queda ningún archivo de respaldo. Este tipo de idioma puede ser útil en Makefiles.Muchos seds tienen la
-i
opción, pero no todos; el posix sed es uno que no. Si busca la portabilidad, por lo tanto, es mejor evitarlo.fuente
... && mv index.html{.tmp,}
sh
(si no recuerdo mal) no tiene esa{...}
expansión. En un Makefile que podría estar usando ensh
lugar de hacerlobash
, por lo que si está buscando la portabilidad (o posixness), deberá evitar esa construcción.Esto hace una sustitución global en el lugar en el archivo index.html. Citar la cadena evita problemas con espacios en blanco en la consulta y el reemplazo.
fuente
use la opción -i de sed, p. ej.
fuente
's/STRING_TO_REPLACE/REPLACE_WITH/g'
-i
realiza la edición de archivos en el lugar , por lo que no tiene sentido combinarlo con la entrada estándar .Para cambiar varios archivos (y guardar una copia de seguridad de cada uno como * .bak):
tomará todos los archivos en el directorio y los reemplazará
|
conx
esto se llama un "pastel Perl" (fácil como un pastel)fuente
sed
como requisito, solo lo usó como la herramienta que ya probó.Debería intentar usar la opción
-i
para la edición in situ.fuente
Si tiene que agregar un enlace, intente esto. Busque la URL como se indica arriba (comenzando con https y terminando con.com aquí) y reemplácela con una cadena de URL. He usado una variable
$pub_url
aquí.s
aquí significa buscar yg
significa reemplazo global.Funciona !
fuente
Advertencia: este es un método peligroso! Abusa de los búferes de E / S en Linux y con opciones específicas de almacenamiento en búfer se las arregla para trabajar en archivos pequeños. Es una curiosidad interesante. ¡Pero no lo use para una situación real!
Además de la
-i
opción desed
usted puede usar latee
utilidad .De
man
:Entonces, la solución sería:
- aquí
tee
se repite para asegurarse de que la tubería esté almacenada. Luego, todos los comandos en la tubería se bloquean hasta que obtienen alguna entrada para trabajar. Cada comando en la tubería comienza cuando los comandos aguas arriba han escrito 1 búfer de bytes (el tamaño se define en alguna parte ) en la entrada del comando. Entonces el último comandotee index.html
, que abre el archivo para escribir y, por lo tanto, lo vacía, se ejecuta después de que la tubería ascendente ha finalizado y la salida está en el búfer dentro de la tubería.Lo más probable es que lo siguiente no funcione:
- ejecutará ambos comandos de la tubería al mismo tiempo sin ningún bloqueo. (Sin el bloqueo de la tubería debe pasar la línea de bytes por línea en lugar de tampón de memoria intermedia. Igual que cuando se ejecuta
cat | sed s/bar/GGG/
. Sin bloqueo es más interactiva y por lo general las tuberías de sólo 2 comandos ejecutar sin memoria intermedia y el bloqueo. Oleoductos más largos se almacenan temporalmente.) Latee index.html
voluntad abra el archivo para escribir y se vaciará. Sin embargo, si activa el almacenamiento en búfer siempre, la segunda versión también funcionará.fuente
>
, pero el punto es que es una solución dañada que probablemente provocará la pérdida de datos).El problema con el comando
es que
file
el shell trunca antes de que sed realmente lo procese. Como resultado, obtienes un archivo vacío.La forma de hacerlo es usar la
-i
edición en el 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 preservar enlaces, puede usar una variable temporal para almacenar la salida de sed antes de volver a escribirla en el archivo, de esta manera:Mejor aún, es probable que el uso en
printf
lugar deecho
desde yaecho
se procese\\
como\
en algunos shells (por ejemplo, guión)fuente
sed 'code' file > file.tmp; cat file.tmp > file; rm file.tmp
Y la
ed
respuesta:Para reiterar lo que respondió codaddict , el shell maneja primero la redirección , borrando el archivo "input.html", y luego el shell invoca el comando "sed" pasándole un archivo ahora vacío.
fuente
ed
versión" de lassed
respuestas? ¿funciona más rápido?sed
s no se implementan-i
para editar en el lugar.ed
es omnipresente y le permite guardar sus ediciones en el archivo original. Además, siempre es bueno tener muchas herramientas en su kit.Puede usar Vim en modo Ex:
%
seleccione todas las líneasx
guardar y cerrarfuente
Estaba buscando la opción donde puedo definir el rango de línea y encontré la respuesta. Por ejemplo, quiero cambiar host1 a host2 de la línea 36-57.
También puede usar la opción gi para ignorar el caso de caracteres.
fuente
Con el debido respeto a las respuestas correctas anteriores, siempre es una buena idea "ejecutar en seco" secuencias de comandos como esa, para que no corrompa su archivo y tenga que comenzar de nuevo desde cero.
Simplemente haga que su secuencia de comandos derrame la salida a la línea de comando en lugar de escribirla en el archivo, por ejemplo, así:
O
De esta manera, puede ver y verificar la salida del comando sin truncar su archivo.
fuente