Tengo un requisito en mi proyecto para reemplazar parte del texto existente en un archivo como foocon algún otro texto como fooofoo:
abc.txt
name
foo
foo1
Entonces intenté:
sed -i "s/foo/fooofoo/g" abc.txt
Sin embargo me sale este error:
sed: opción ilegal
i
Encontré en el manual que tengo que usar:
sed -i\ "s/foo/fooofoo/g" abc.txt
Sin embargo, esto tampoco funciona.
Encontré alternativas perly awktambién, pero una solución en Solaris sedsería muy apreciada.
Estoy usando esta versión de bash:
GNU bash, versión 3.2.57 (1) -release (sparc-sun-solaris2.10)
text-processing
sed
solaris
tpsaitwal
fuente
fuente

/usr/gnu/bin/sedpara obtener soporte -i.Respuestas:
Uso
ed. Está disponible en la mayoría de las plataformas y puede editar sus archivos en el lugar.Dado que
sedse basa enedla sintaxis para reemplazar patrones es similar:fuente
edlugar deexsolo curiosidad? (Sé que ambos son compatibles con POSIX y me he vinculado a las especificaciones.))ex? Para responder a su pregunta: como nunca usoexno estoy familiarizado con él. por cierto, he visto configuraciones dondeedestaba presente peroexno estaba (pero no al contrario) ... el más notable es mi computadora portátil :)excomandos. Todos losvicomandos que puede escribir que comienzan con dos puntos sonexcomandos. Por supuesto, hay algunas extensiones específicas de Vim, pero solo el conjunto central de comandos es increíblemente potente y flexible y es suficiente para las ediciones con script.exy aún noed.Si no puede instalar GNU sed, use:
Esto utiliza la redirección para enviar la salida de sed a un archivo temporal. Si sed se completa con éxito, esto se sobrescribe
abc.txtcon el archivo temporal.Como se puede ver en el código fuente de GNU sed , esto es exactamente lo que
sed -ihace. Entonces, esto es casi tan eficiente comosed -i.Si ya existe una posibilidad
abc.tmp, es posible que desee utilizarmktempuna utilidad similar o similar para generar el nombre único para el temporal.fuente
ed, ya que lee todo el archivo en la memoria.Si quieres el equivalente de
sed -i.bak, es bastante simple.Considere este script para GNU sed:
Simplemente podemos reemplazar la línea marcada con
Esto mueve el archivo existente para que sea una copia de seguridad y escribe un nuevo archivo.
Si queremos el equivalente de
entonces es un poco más complejo. Podemos abrir el archivo para leerlo como entrada estándar, luego desvincularlo, antes de dirigir la salida de sed para reemplazarlo:
Hacemos esto en un sub-shell, para que nuestro stdin original todavía esté disponible después de esto. Es posible cambiar las entradas y volver sin un subshell, pero de esta manera me parece más claro.
Tenga en cuenta que tenemos cuidado de copiar primero, en lugar de crear un nuevo
fooarchivo; esto es importante si el archivo se conoce por más de un nombre (es decir, tiene enlaces duros) y desea asegurarse de no romper los enlaces .fuente
Primero, debe saber que el
i\comando al que se refiere es para insertar una línea de texto, no para guardar el texto editado nuevamente en el archivo. No hay una forma de POSIX especificada para usarsedpara eso.Lo que puede hacer es usar
ex, que está especificado por POSIX :El
xcomando es para "guardar y salir". También puedes usarlowqperoxes más corto.El
%signo al comienzo del comando sustituto significa "Aplicar este comando a cada línea en el búfer". Podrías usar1,$s/find/replace/gtambién.Una diferencia importante entre
exysedes quesedes un editor de flujo . Solo funciona secuencialmente, línea por línea.exes mucho más flexible que eso, y de hecho puedes editar archivos de texto interactivos directamente enex. Es el predecesor inmediato devi.fuente
Usando
sedy sin archivo temporal visible :Puede evitar crear un "archivo temporal" visible separado :
Explicación
Los sistemas tipo Unix en realidad no eliminan el contenido del archivo del disco hasta que ambos estén desvinculados en el sistema de archivos y no se abran en ningún proceso. Entonces puede hacer
exec 3<para abrir el archivo en el shell para leer en el descriptor de archivo 3,rmel archivo (que lo desvincula del sistema de archivos), y luego llamarsedcon el descriptor de archivo 3 utilizado como entrada.Tenga en cuenta que esto es muy diferente de esto:
La diferencia es que cuando lo hace en un comando, el shell simplemente abre el mismo archivo tanto para leer como para escribir con la opción de truncar el archivo, ya que sigue siendo el mismo archivo, pierde el contenido. Pero si lo abre para leerlo, luego
rmabre el mismo nombre de ruta para escribir, en realidad está creando un nuevo archivo con el mismo nombre de ruta (pero en un nuevo inodo y ubicación de disco, ya que el original todavía está abierto): entonces los contenidos aún están disponibles.Luego, una vez que haya terminado, puede cerrar el descriptor de archivo que abrió anteriormente (eso es lo que hace la
exec 3<&-sintaxis especial), que libera el archivo original para que el sistema operativo pueda eliminar (marcar como no utilizado) su espacio en disco.Advertencias
Hay algunas cosas a tener en cuenta sobre esta solución:
Solo obtiene una "lectura" a través del contenido: no hay una forma portátil de que un shell "busque" de nuevo en el descriptor de archivo, por lo que una vez que un programa lee algunos de los contenidos, otros programas solo verán el resto del archivo. Y
sedleerá todo el archivo.Hay una pequeña posibilidad de que su archivo original se pierda si su shell / script / sed se mata antes de que se haga.
fuente
perl -ies otra buena opción. La pregunta solicitó específicamente una solución compatible con Solaris 'sed, en contraste con las soluciones conperlyawkque mencionaron que ya se encuentran. Además, mi respuesta tenía como objetivo principal agregar algo que pensé que era útil saber y que faltaba en cualquiera de las otras respuestas.