Tengo una situación en la que quiero que un script bash reemplace una línea completa en un archivo. El número de línea es siempre el mismo, por lo que puede ser una variable codificada.
No estoy tratando de reemplazar alguna subcadena en esa línea, solo quiero reemplazar esa línea completamente con una nueva línea.
¿Hay algún método bash para hacer esto (o algo simple que pueda ser arrojado a un script .sh)?
sed: -e expression #1, char 26: unknown option to ``s'
y mi línea es:sed -i '7s/.*/<param-value>http://localhost:8080/ASDF/services/REWS.REWSHttpSoap12Endpoint/</param-value>/' $TCE_SVN_HOME\trunk\tce\EWC\WebContent\WEB-INF\web.xml
. ¿Alguna idea?/
en el texto de reemplazo se interpretará como la barra diagonal de cierre dels
comando a menos que se haya escapado (\/
). Sin embargo, lo más fácil de hacer es elegir un personaje diferente sin usar como delimitador. Por ejemplo,sed -i '7s{.*}{<param-value>http://...}' $TCE_SVN_HOME/trunk...
.s
determina el delimitador. Entonces, para cambiar su comando para usar, por ejemplo#
, sería así:sed -i '7s#.*#<param-value>http://localhost:8080/ASDF/services/REWS.REWSHttpSoap12Endpoint/</param-value>#'
-e
if-i
; por lo tanto, el comando correcto se convierte en:sed -e 'Ns/.*/replacement-line/' -i '' file.txt
De hecho, usé este script para reemplazar una línea de código en el archivo cron en los servidores UNIX de nuestra compañía hace un tiempo. Lo ejecutamos como script de shell normal y no tuvimos problemas:
Esto no va por número de línea, pero puede cambiar fácilmente a un sistema basado en un número de línea colocando el número de línea antes
s/
y colocando un comodín en lugar dethe_original_line
.fuente
sed -e "s/.../.../" /dir/file > /dir/temp_file
sed -e "s/.../.../" /dir/file > /dir/file
Supongamos que desea reemplazar la línea 4 con el texto "diferente". Puedes usar AWK así:
AWK considera que la entrada son "registros" divididos en "campos". Por defecto, una línea es un registro.
NR
es la cantidad de registros vistos.$0
representa el registro completo actual (mientras que$1
es el primer campo del registro y así sucesivamente; de forma predeterminada, los campos son palabras de la línea).Entonces, si el número de línea actual es 4, imprima la cadena "diferente" pero de lo contrario imprima la línea sin cambios.
En AWK, el código del programa incluido en
{ }
ejecuciones una vez en cada registro de entrada.Debe citar el programa AWK en comillas simples para evitar que el shell intente interpretar cosas como la
$0
.EDITAR: Un programa AWK más corto y elegante de @chepner en los comentarios a continuación:
Solo para el registro (es decir, la línea) número 4, reemplace todo el registro con la cadena "diferente". Luego, para cada registro de entrada, imprima el registro.
¡Claramente mis habilidades de AWK están oxidadas! Gracias, @chepner.
EDITAR: y vea también una versión aún más corta de @Dennis Williamson:
Los comentarios explican cómo funciona esto:
1
siempre evalúa verdadero, por lo que el bloque de código asociado siempre se ejecuta. Pero no hay un bloque de código asociado, lo que significa que AWK realiza su acción predeterminada de solo imprimir toda la línea. AWK está diseñado para permitir programas concisos como este.fuente
awk 'NR==4 {$0="different"} { print }' input_file.txt
.awk 'NR==4 {$0="different"}1' input_file.txt
1
? (Nota: ¡Lo probé y de hecho funciona! Simplemente no entiendo cómo.)Dado este archivo de prueba (test.txt)
el siguiente comando reemplazará la primera línea a "texto de nueva línea"
Resultado:
más información se puede encontrar aquí
http://www.thegeekstuff.com/2009/11/unix-sed-tutorial-append-insert-replace-and-count-file-lines/
fuente
sed '1 cnewline text' test.txt
lo haría tambiénen bash, reemplace N, M por los números de línea y xxx aaa por lo que desee
EDITAR
De hecho, en esta solución hay algunos problemas, con los caracteres "\ 0" "\ t" y "\"
"\ t", se puede resolver poniendo IFS = antes de leer: "\", al final de la línea con -r
pero para "\ 0", la variable se trunca, no existe una solución en bash puro: Asigne una cadena que contenga caracteres nulos (\ 0) a una variable en Bash Pero en el archivo de texto normal no hay caracteres nul \ 0
Perl sería una mejor opción
fuente
fuente
Excelente respuesta de Chepner. Me está funcionando en bash Shell.
aquí
index
- Línea nonewLine
- nueva cadena de línea que queremos reemplazar.De manera similar, el siguiente código se usa para leer una línea particular en el archivo. Esto no afectará el archivo real.
aquí
!d
: eliminará las líneas que no sean la línea no$index
Por lo tanto, obtendremos el resultado como una cadena de línea de no$index
en el archivo.fuente
${newline}
?En mac usé
fuente
Incluso puede pasar parámetros al comando sed:
test.sh
salida original.dat:
Ejecutar ./test.sh proporciona el nuevo output.dat
fuente
line=5; sed -i "${line}s/.*/replaced by '$i'!/" output.dat