Insertar una cadena al final justo antes de la última línea de un archivo mediante sed | Algo de Linux

lunes, 27 de mayo de 2013

Insertar una cadena al final justo antes de la última línea de un archivo mediante sed

En muchas ocasiones tenemos que insertar, mediante bash, una cadena de texto al final de un archivo, justo antes de la última línea, como por ejemplo, en el archivo /etc/rc.local o /etc/gdm3/PostSession/Default, donde hay que insertar los comandos antes de la línea que dice: "exit 0".

En linux tenemos muchas formas de hacerlo, pero para mí la más sencilla es ésta:

# sed -i '$ i\cadena' archivo

Vamos a verlo con un ejemplo:

Si quiero lanzar ocsinventory-agent en el inicio de una máquina, tengo que hacer una llamada a ocsinventory-agent en el archivo /etc/rc.local.

El archivo /etc/rc.local tiene por defecto el siguiente contenido:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

exit 0

Como lo que necesito es insertar la cadena "ocsinventory-agent" justo antes de la línea que dice "exit 0", lo que tengo que hacer es ejecutar el siguiente comando:

# sed -i '$ i\ocsinventory-agent\n' /etc/rc.local

Como se puede ver, inserto in-line ( parámetro -i) la cadena ocsinventory-agent y un salto de línea en el archivo /etc/rc.local.

Después de ejecutar el comando, el archivo quedaría así:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

ocsinventory-agent 

exit 0

Un detalle importante: Debemos tener cuidado si ejecutamos el comando más de una vez porque estaremos insertando varias veces la misma cadena. Si queremos ejecutar el comando dentro de un script, de tal manera que la cadena se inserte tan sólo una vez, deberíamos controlarlo de algún modo. Por ejemplo, así:

# grep -q ocsinventory-agent /etc/rc.local 2> /dev/null || sed -i '$ i\ocsinventory-agent\n' /etc/rc.local

De este modo, la inserción sólo se realizará cuando la cadena no estuviera ya insertada en el archivo.

7 comentarios:

Anónimo dijo...

Creo que es mas sencillo con echo 'cadena' >> archivo

Saludos cordiales.

Esteban M. Navas Martín dijo...

No es lo mismo. Se trata de insertar una cadena justo antes de la última línea. Lo que tú dices añade la cadena al final del archivo.

Anónimo dijo...

hola amigo, me gusto mucho tu solucion. Mira yo tengo que hacer algo similar. Haber si me puedes hechar una manito. tengo un archivo que contiene cadenas como estas:
qwieqwehqwbr
123ihodohiohfhiosaf
q3qwedwadj
2313ejwd
332rjijfhdshfhsfiifhdhihi
12312ewqdfer44fff
gfdgdfg
ewre
yy yo necesito insertar o mas bien dicho concatenar una cadena fija en cada linea del tipo 123ert213 para que el archivo me quede asi

qwieqwehqwbr 123ert213
123ihodohiohfhiosaf 123ert213
q3qwedwadj 123ert213
2313ejwd 123ert213
332rjijfhdshfhsfiifhdhihi 123ert213
12312ewqdfer44fff 123ert213
gfdgdfg 123ert213
ewre 123ert213
y la verdad no he encontrado la forma de hacerlo. agradeceria tu ayuda. saludos

Esteban M. Navas Martín dijo...

Eso es muy sencillo. Tan sólo tienes que utilizar sed de la siguiente manera:

sed 's/$/ 123ert213/g' fichero

Y si quieres que el contenido se inserte directamente en el archivo, utiliza el parámetro -i:

sed -i 's/$/ 123ert213/g' fichero

Esteban M. Navas Martín dijo...

Y si quisieras insertar la cadena al principio del fichero, en lugar de hacerlo al final:

sed -i 's/^/123ert213 /g' fichero

beita dijo...

Buenos días,

Estoy buscando hacer algo parecido. Tengo un archivo con direcciones ftp:
ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCA/001/932/555/GCA_001932555.1_ASM193255v1
ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCA/000/196/795/GCA_000196795.1_ASM19679v1

Para poder descargarme los archivos tendría que añadir al final de cada línea, parte de esa linea y concatenarlo con esta string "_genomic.fna.gz". El resultado sería el siguiente:

ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCA/001/932/555/GCA_001932555.1_ASM193255v1/GCA_001932555.1_ASM193255v1__genomic.fna.gz

Entiendo la parte en la que se añade _genomic.fna.gz porque sería igual que el ejemplo que has explicado pero no sabría como indicarle que tiene que copiar desde / hacia adelante.

Cualquier ayuda será bienvenida

Muchas gracias

Beatriz

Esteban M. Navas Martín dijo...

Hola, Beatriz. No entiendo qué quieres decir que no sabrías como indicarle que tiene que copiar desde / hacia adelante... Por el ejemplo que pones, tan sólo tienes que reeemplazar el final de cada línea ($) con el texto "_genomic.fna.gz" y eso es algo tan sencillo como hacer lo siguiente:
sed -i 's/$/_genomic.fna.gz/g' archivodireccionesftp