Me gustaría ejecutar un buscar y reemplazar en un archivo HTML a través de la línea de comandos.

Mi mando se ve algo como esto:

sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index.html

Cuando ejecuto esto y buscar en el archivo después, es vacío. Se elimina 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

La stdout es el contenido del archivo, y el buscar y reemplazar se ha ejecutado.

Por qué está sucediendo esto?

InformationsquelleAutor BBales | 2011-03-02

13 Comentarios

  1. 881

    Cuando el shell ve > index.html en la línea de comando que se abre el archivo index.html para escrito, eliminando todo su contenido anterior.

    Para solucionar esto usted necesita para pasar el -i opción para sed para hacer los cambios en línea y crear una copia de seguridad del archivo original antes de que haga 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.

    • Diciendo truncates the file en lugar de opens the file probablemente hace más clara.
    • Al menos en mi mac, la primera sugerencia no funciona… si vas a hacer en el lugar de reemplazo en un archivo, usted tiene que especificar una extensión. Usted puede, al menos, pasar un cero de longitud de extensión: la sed-i » s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
    • para las variables sed-i.bak ‘s/’$busqueda’/’$sustituir a’/g’ index.html
    • Gracias. No menciona en ningún lugar que la extensión de copia de seguridad es una necesidad en Mac OSX. Estaba tirando invalid character code f error cuando lo he probado con un archivo llamado foo sin proporcionar ningún tipo de extensión..
    • en osx, utilizar una cadena vacía » como el parámetro -i, como: sed -i '' 's/blah/xx/g'
    • pero lo que es tuyo .bak después de sed -i ?
    • usando cygwin en Win7 64 tengo los archivos temporales y los archivos originales se habían ido, no hay reemplazos.
    • Gracias por tu comentario. Odio la creación de un nuevo archivo bak en mac. Su respuesta soluciona mi problema.
    • Para usuarios de Mac: también puede instalar el gnu-sed para usar en lugar de las versiones de BSD usar en Mac. Ver aquí: apple.stackexchange.com/a/195595
    • Por python, la filosofía, la «explícito es mejor que la implícita», aquí va una exactamente el mismo pero la versión más legible de la orden: sed --in-place ".bak" s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
    • Solo para aclarar un poco más. Si hubiera sido sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index_new.html hubiera funcionado. La confusión proviene del hecho de que estamos leyendo de izquierda a derecha. Lo que sucede es que aunque el archivo se trunca primera en preparación para el comando sed que sigue, que acaba de operación en un archivo vacío.

  2. 201

    Una alternativa útil, el patrón es:

    sed -e 'script script' index.html > index.html.tmp && mv index.html.tmp index.html

    Que tiene el mismo efecto, sin el uso de la -i opción, y además significa que, si la sed script falla por alguna razón, el archivo de entrada no es una paliza. Además, si la edición es correcta, no hay ningún archivo de copia de seguridad de la izquierda se extiende a su alrededor. Este tipo de lenguaje puede ser útil en los Makefiles.

    Un buen montón de sed tiene el -i opción, pero no todos ellos; el posix sed es uno de los que no. Si usted está apuntando para la portabilidad, por lo tanto, es mejor evitar.

    • +1 para la consideración de la portabilidad
    • +1 para ningún archivo de copia de seguridad alrededor y no clobbering archivo de entrada si editar falla. Funcionó a la perfección en mac.
    • La única solución que trabajó para mí en Win7 64 Cygwin
    • Trabajó para mí perfectamente. Gracias! (en un Mac)
    • Esto funcionó para mí perfectamente donde en Ubuntu Server 14.04 sed-seguí poniendo a cero el archivo.
    • Muy menor de mejora: ... && mv index.html{.tmp,}
    • De hecho, es probablemente lo usaría si estuviera escribiendo – estoy de acuerdo es más limpio – pero sh (si no recuerdo mal) no tiene que {...} de expansión. En un archivo Make de que usted podría estar usando sh en lugar de bash, así que si usted está apuntando para la portabilidad (o posixness), entonces usted tendrá que evitar que las obras de construcción.
    • Muy bien señala @NormanGray.
    • O más corto: mv index.html $(echo index.html | sed -e 'script')

  3. 86
    sed -i 's/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' index.html

    Esto hace un mundial en lugar de la sustitución en el archivo index.html. Citando a la cadena evita problemas con los espacios en blanco en la consulta y de reemplazo.

  4. 56

    usar sed de la opción-i, por ejemplo,

    sed -i bak -e s/STRING_TO_REPLACE/REPLACE_WITH/g index.html
    • funciona en mí mac. El aceptó respuesta no
    • ¿Qué significa esto? sed: -no puede ser utilizado con stdin
    • Recuerde que rodean su patrón entre comillas si contiene espacios en blanco – 's/STRING_TO_REPLACE/REPLACE_WITH/g'
    • realiza la edición en el lugar de archivos, por lo que no tiene sentido que se combinan con el stdin de entrada.
    • Esto podría funcionar en macOS, pero no en Arch Linux para mí.
  5. 18

    Para cambiar varios archivos (y guardar una copia de seguridad de cada uno como *.bak):

    perl -p -i -e "s/\|/x/g" *  

    tendrá todos los archivos en el directorio y reemplazar | con x
    esto se llama un «Perl circular» (muy fácil)

    • Es bueno ver a alguien que este dispuesto a mirar el enunciado del problema, y no sólo las etiquetas. OP no especificar sed como un requisito, sólo se utiliza como la herramienta que ya ha probado.
  6. 6
    sed -i.bak "s#https.*\.com#$pub_url#g" MyHTMLFile.html

    Si usted tiene un enlace a agregarse, prueba este. La búsqueda de la URL como en el anterior (que comienza con https y terminando with.com aquí) y reemplazarlo con una cadena de dirección URL. He utilizado una variable $pub_url aquí. s aquí los medios de búsqueda y g medios de sustitución global.

    Funciona !

  7. 5

    Advertencia: este es un método peligroso! Se abusa de la 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 de sed
    usted puede utilizar el tee utilidad.

    De man:

    tee – lea de la entrada estándar y escribe en la salida estándar y archivos

    Así, la solución sería:

    sed s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html | tee | tee index.html

    — aquí el tee se repite para asegurarse de que la tubería se almacenan en la memoria. A continuación, todos los comandos en la tubería son bloqueados hasta llegar a la entrada de trabajar. Cada comando en la tubería se inicia cuando la parte de arriba de los comandos de haber escrito 1 buffer de bytes (el tamaño se define en algún lugar) a la entrada de la orden. Así que el último comando tee index.html, que se abre el archivo para escritura y, por tanto, la vacía, se ejecuta después de la tubería aguas arriba ha terminado y la salida es en el buffer dentro de la canalización.

    Más probable es que el siguiente no funcionará:

    sed s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html | tee index.html

    , serán de ejecutar los comandos de la tubería al mismo tiempo sin ningún tipo de bloqueo. (Sin bloqueo de la tubería debe pasar los bytes línea por línea en lugar de la memoria intermedia de la memoria intermedia. Igual que cuando se ejecute cat | sed s/bar/GGG/. Sin bloqueo, es más interactivo y generalmente tuberías de 2 comandos se ejecutan sin búfer y el bloqueo. Ya que las tuberías están en el búfer.) El tee index.html se abre el archivo para escritura y se vacía. Sin embargo, si activa el almacenamiento en búfer de siempre, la segunda versión será trabajar demasiado.

    • El archivo de salida del tee es también abrió inmediatamente, resultando en un vacío index.html para el comando completo.
    • Esto corrupto cualquier archivo de entrada es mayor que el tubería de búfer (que normalmente es de 64 kb). (@sjngm: el archivo no se trunca al instante como con >, pero el punto destaca que la rotura de una solución que es probable que resulte en la pérdida de datos).
  8. 4

    El problema con el comando

    sed 'code' file > file

    es que file es truncado por el shell antes de sed que de hecho se pone a procesar. Como resultado, se obtiene un archivo vacío.

    La sed manera de hacer esto es utilizar -i a editar en el lugar, como otras respuestas sugeridas. Sin embargo, esto no es siempre lo que usted desea. -i va a crear un archivo temporal que se usa para reemplazar el archivo original. Esto es problemático si el archivo original fue un enlace (el enlace será reemplazado por un archivo regular). Si usted necesita para preservar los vínculos, usted puede usar una variable temporal para almacenar el resultado de sed antes de escribir de nuevo para el archivo, como este:

    tmp=$(sed 'code' file); echo -n "$tmp" > file

    Mejor aún, utilice printf en lugar de echo desde echo es probable que el proceso de \\ como \ en algunas de las conchas (por ejemplo, dash):

    tmp=$(sed 'code' file); printf "%s" "$tmp" > file
    • +1 para la preservación de los vínculos. También funciona con un archivo temporal: sed 'code' file > file.tmp; cat file.tmp > file; rm file.tmp
  9. 3

    Y la ed respuesta:

    printf "%s\n" '1,$s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' w q | ed index.html

    A reiterar lo que codaddict respondió, el shell se encarga de la redirección primera, la aniquilación de la «input.html» el archivo, y luego la shell invoca la «sed» comando pasando ahora un archivo vacío.

    • pregunta rápida, por qué la gente sigue dando la «ed versión» de sed respuestas? hace que funcione más rápido?
    • Algunos seds no implementar -i a editar en el lugar. ed es ubicuo y permite guardar las modificaciones en el archivo original. Además de que siempre es bueno tener un montón de herramientas en el kit.
    • ok, genial. así, el rendimiento de sabios, que son el mismo, supongo. gracias!
  10. 2

    Puede usar Vim en modo Ex:

    ex -sc '%s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g|x' index.html
    1. % seleccione todas las líneas

    2. x guardar y cerrar

  11. 0

    Yo estaba buscando la opción en la que podemos definir la línea y encontró la respuesta. Por ejemplo quiero cambiar el host1 a host2 de la línea 36-57.

    sed '36,57 s/host1/host2/g' myfile.txt > myfile1.txt

    Puede utilizar gi también la opción de ignorar el carácter de caso.

    sed '30,40 s/version/story/gi' myfile.txt > myfile1.txt
  12. 0

    Con todo el debido respeto a las anteriores respuestas correctas, es siempre una buena idea «dry run» scripts como que, para que no se corrompa el archivo y tiene que empezar de nuevo desde cero.

    Acaba de obtener la secuencia de comandos para el derrame de la salida a la línea de comandos en lugar de escribir en el archivo, por ejemplo, como que:

    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 usted puede ver y comprobar la salida de los comandos sin conseguir su archivo truncado.

Dejar respuesta

Please enter your comment!
Please enter your name here