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.