Ediciones en el lugar con sed en OS X


142

Me gustaría editar un archivo con sed en OS X. Estoy usando el siguiente comando:

sed 's/oldword/newword/' file.txt

La salida se envía al terminal. file.txt no se modifica. Los cambios se guardan en file2.txt con este comando:

sed 's/oldword/newword/' file1.txt > file2.txt

Sin embargo, no quiero otro archivo. Solo quiero editar file1.txt . ¿Cómo puedo hacer esto?

He probado la bandera -i. Esto da como resultado el siguiente error:

sed: 1: "file1.txt": invalid command code f

2
¿Cuál es el comando exacto que estás usando cuando pruebas la -ibandera?
eldarerathis

Respuestas:


282

Puede usar el -iindicador correctamente proporcionándole un sufijo para agregar al archivo respaldado. Extendiendo su ejemplo:

sed -i.bu 's/oldword/newword/' file1.txt

Le dará dos archivos: uno con el nombre file1.txtque contiene la sustitución y otro con el nombre file1.txt.buque tiene el contenido original.

Levemente peligroso

Si desea sobrescribir destructivamente el archivo original, use algo como:

sed -i '' 's/oldword/newword/' file1.txt
      ^ note the space

Debido a la forma en que se analiza la línea, se requiere un espacio entre el indicador de opción y su argumento porque el argumento es de longitud cero.

Aparte de posiblemente destrozar su original, no estoy al tanto de ningún peligro adicional de engañar a sed de esta manera. Sin embargo, debe tenerse en cuenta que si esta invocación sedes parte de un script, The Unix Way ™ (IMHO) sería usar de manera sedno destructiva, probar que salió limpiamente y solo luego eliminar el archivo extraño.


Tienes razón, estaba omitiendo la extensión después de la bandera -i. ¿Es -i''peligroso por alguna razón que no sea desordenar el archivo original (y no tener una copia de seguridad)?
Domingo lunes

Según la sedpágina del manual, si se queda sin espacio en disco en el dispositivo, podría dañar un archivo a mitad de camino y tener un resultado de salida incorrecto. Si está trabajando bajo control de fuente local sed -i ""sin copias de seguridad, debería estar bien la mayor parte del tiempo (o justo git init && git add -A . && git commit -m 'backup'antes de ejecutar sed en -imodo).
cfeduke

2
Encontré la parte ligeramente peligrosa particularmente útil. +1
Andre

55
BSD sed requiere que no haya espacio después de la bandera -i. Entonces,-i'' es válido, pero -i ''no lo es.
Todd A. Jacobs

3
Argh! ¡BSD sed ignora el carácter '\ n' e imprime 'n' en su lugar! ¡Solo voy a reemplazar BSD sed con GNU sed en mi mac!
nterry

20

Tengo un problema similar con MacOS

sed -i '' 's/oldword/newword/' file1.txt

no funciona pero

sed -i"any_symbol" 's/oldword/newword/' file1.txt

funciona bien.


Esto es ahora al revés. sed -i '' <file>funciona pero sed -i'' <file>ya no funciona
Zohaib Amanzai


4

Puede usar -i''( --in-place) sedcomo ya se sugirió. Ver: El -iargumento en el lugar , sin embargo, tenga en cuenta que la -iopción es extensiones de FreeBSD no estándar y puede no estar disponible en otros sistemas operativos. En segundo lugar sedes un S TREAM ED itor, no un editor de archivos .


La forma alternativa es utilizar la sustitución integrada en el modo Vim Ex, como:

$ ex +%s/foo/bar/g -scwq file.txt

y para múltiples archivos:

$ ex +'bufdo!%s/foo/bar/g' -scxa *.*

Para editar todos los archivos de forma recursiva, puede usar **/*.*si shell lo admite (habilitar por shopt -s globstar).


Otra forma es usar gawky su nueva extensión "in situ" como:

$ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1

4

Esto crea archivos de respaldo. Por ejemplo, sed -i -e 's/hello/hello world/' testfilepara mí, crea un archivo de respaldo, testfile-e, en el mismo directorio.


Lo mismo aquí con Mac OS Catalina. Pasar ambos -i y -e por separado (¡NO juntos!) Crea un archivo de respaldo con '-e' agregado.
Daniel Kesner

1

Puedes usar:

sed -i -e 's/<string-to-find>/<string-to-replace>/' <your-file-path>

Ejemplo:

sed -i -e 's/Hello/Bye/' file.txt

Esto funciona perfectamente en Mac .


2
Esto crea un archivo de respaldo para mí en Mac OS Catalina con '-e' agregado.
Daniel Kesner

Esto está mal para macOS. Por favor, eche un vistazo a la página "man sed" allí. -irequiere un argumento para macOS. Como no especifica uno, lo utiliza -e, lo que resulta en tener un segundo archivo -eadjunto. -eno existe en macOS, lo es -E. Entonces, el comando correcto para macOS essed -i '' -E 's/Hello/Bye/' file.txt
Marc J. Schmidt
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.