sed editar archivo en su lugar
Estoy tratando de averiguar si es posible editar un archivo en un solo comando sed sin manualmente transmitir el contenido editado a un nuevo archivo y luego cambiar el nombre del nuevo archivo al nombre del archivo original. Probé la opción -i
pero mi sistema Solaris dijo que -i
es una opción ilegal. ¿Hay una manera diferente?
13 answers
El -i
option transmite el contenido editado a un nuevo archivo y, de todos modos, lo cambia de nombre entre bastidores.
Ejemplo:
sed -i 's/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' filename
Y
sed -i '' 's/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' filename
En macOS .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-10 12:23:03
En un sistema donde sed
no tiene la capacidad de editar archivos en su lugar, creo que la mejor solución sería usar perl
:
perl -pi -e 's/foo/bar/g' file.txt
Aunque esto crea un archivo temporal, reemplaza al original porque se ha suministrado un sufijo/extensión vacío en su lugar.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-03 04:20:22
Tenga en cuenta que en OS X puede obtener errores extraños como "código de comando no válido" u otros errores extraños al ejecutar este comando. Para solucionar este problema intente
sed -i '' -e "s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g" <file>
Esto se debe a que en la versión OSX de sed
, la opción -i
espera un argumento extension
por lo que su comando se analiza como el argumento extension
y la ruta del archivo se interpreta como el código de comando. Fuente: https://stackoverflow.com/a/19457213
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:30
Lo siguiente funciona bien en mi mac
sed -i.bak 's/foo/bar/g' sample
Estamos reemplazando foo con bar en el archivo de ejemplo. La copia de seguridad del archivo original se guardará en la muestra.bak
Para editar en línea sin copia de seguridad, utilice el siguiente comando
sed -i'' 's/foo/bar/g' sample
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-09 08:27:56
Una cosa a tener en cuenta, sed
no puede escribir archivos por sí solo, ya que el único propósito de sed es actuar como un editor en el "flujo" (es decir, tuberías de stdin, stdout, stderr y otros >&n
buffers, sockets y similares). Con esto en mente, puede usar otro comando tee
para escribir la salida de nuevo en el archivo. Otra opción es crear un parche a partir de canalizar el contenido en diff
.
Método Ete
sed '/regex/' <file> | tee <file>
Parche método
sed '/regex/' <file> | diff -p <file> /dev/stdin | patch
ACTUALIZACIÓN:
También, tenga en cuenta que patch hará que el archivo cambie desde la línea 1 de la salida diff:
El parche no necesita saber a qué archivo acceder, ya que se encuentra en la primera línea de la salida de diff:
$ echo foobar | tee fubar
$ sed 's/oo/u/' fubar | diff -p fubar /dev/stdin
*** fubar 2014-03-15 18:06:09.000000000 -0500
--- /dev/stdin 2014-03-15 18:06:41.000000000 -0500
***************
*** 1 ****
! foobar
--- 1 ----
! fubar
$ sed 's/oo/u/' fubar | diff -p fubar /dev/stdin | patch
patching file fubar
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-17 08:29:21
No es posible hacer lo que quieras con sed
. Incluso las versiones de sed
que admiten la opción -i
para editar un archivo en su lugar hacen exactamente lo que usted ha indicado explícitamente que no desea: escriben en un archivo temporal y luego cambian el nombre del archivo. Pero tal vez solo puede usar ed
. Por ejemplo, para cambiar todas las ocurrencias de foo
a bar
en el archivo file.txt
, puede hacer:
echo ',s/foo/bar/g; w' | tr \; '\012' | ed -s file.txt
La sintaxis es similar a sed
, pero ciertamente no es exactamente la misma.
Pero tal vez usted debería considerar por qué no desea usar un archivo temporal renombrado. Incluso si no tiene un -i
compatible con sed
, puede escribir fácilmente un script para hacer el trabajo por usted. En lugar de sed -i 's/foo/bar/g' file
, podrías hacer inline file sed 's/foo/bar/g'
. Tal guión es trivial de escribir. Por ejemplo:
#!/bin/sh -e
IN=$1
shift
trap 'rm -f $tmp' 0
tmp=$( mktemp )
<$IN "$@" >$tmp && cat $tmp > $IN # preserve hard links
Debe ser adecuado para la mayoría de los usos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-02 19:46:40
Sed admite la edición in situ. De man sed
:
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if extension supplied)
Ejemplo:
Digamos que tienes un archivo hello.txt
con el texto:
hello world!
Si desea mantener una copia de seguridad del archivo anterior, use:
sed -i.bak 's/hello/bonjour' hello.txt
Terminarás con dos archivos: hello.txt
con el contenido:
bonjour world!
Y hello.txt.bak
con el contenido antiguo.
Si no desea mantener una copia, simplemente no pase el parámetro de extensión.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-22 16:27:51
Podrías usar vi
vi -c '%s/foo/bar/g' my.txt -c 'wq'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-30 09:04:34
mv file.txt file.tmp && sed 's/foo/bar/g' < file.tmp > file.txt
Debe preservar todos los enlaces duros, ya que la salida se dirige hacia atrás para sobrescribir el contenido del archivo original, y evita cualquier necesidad de una versión especial de sed.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-08 05:38:51
Si está reemplazando la misma cantidad de caracteres y después de leer cuidadosamente edición"in-place" de archivos...
También puede usar el operador de redirección <>
para abrir el archivo para leer y escribir:
sed 's/foo/bar/g' file 1<> file
Verlo en vivo:
$ cat file
hello
i am here # see "here"
$ sed 's/here/away/' file 1<> file # Run the `sed` command
$ cat file
hello
i am away # this line is changed now
De Bash Reference Manual → 3.6.10 Apertura de Descriptores de Archivo para Lectura y Escritura :
El operador de redirección
[n]<>word
Hace que el archivo cuyo nombre es la expansión de word sea abierto para lectura y escritura en el descriptor de fichero n, o en el descriptor de fichero 0 si no se especifica n. Si el archivo no existe, se crea.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-14 14:15:00
No especificó qué shell está utilizando, pero con zsh podría usar la construcción =( )
para lograr esto. Algo parecido a:
cp =(sed ... file; sync) file
=( )
es similar a >( )
pero crea un archivo temporal que se elimina automáticamente cuando cp
termina.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-02 19:09:48
Como dijo Moneypenny en Skyfall: "A veces las viejas costumbres son las mejores." Kincade dijo algo similar más tarde.
Print printf', s / false / true / g\nw\n ' / ed {YourFileHere}
Feliz edición en su lugar. Añadido '\nw\n' para escribir el archivo. Disculpas por la demora en responder a la solicitud.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-18 18:09:07
Muy buenos ejemplos. Tuve el reto de editar en su lugar muchos archivos y la opción-i parece ser la única solución razonable usarlo dentro del comando find. Aquí el script para añadir "version:" delante de la primera línea de cada archivo:
find . -name pkg.json -print -exec sed -i '.bak' '1 s/^/version /' {} \;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-07 11:07:23