sustituir reemplazar lineas linea insertar especiales espacios eliminar caracteres caracter blanco sed awk

lineas - sed reemplazar/



Inserta una línea en el número de línea específico con sed o awk (8)

Tengo un archivo de script que necesito modificar con otra secuencia de comandos para insertar un texto en la octava línea.

Cadena para insertar: Project_Name=sowstest , en un archivo llamado start .

Traté de usar awk y sed, pero mi comando se confunde.


OS X / macOS sed

El -i funciona de forma diferente en macOS sed que en GNU sed .

Esta es la manera de usarlo en macOS / OS X:

sed -i '''' ''8i/ 8 This is Line 8'' FILE

Ver man 1 sed para más información.


POSIX sed (y, por ejemplo, el sed OS X, el sed continuación) requieren que i sea ​​seguido por una barra invertida y una nueva línea. Además, al menos, sed OS X no incluye una nueva línea después del texto insertado:

$ seq 3|gsed ''2i1.5'' 1 1.5 2 3 $ seq 3|sed ''2i1.5'' sed: 1: "2i1.5": command i expects / followed by text $ seq 3|sed $''2i///n1.5'' 1 1.52 3 $ seq 3|sed $''2i///n1.5/n'' 1 1.5 2 3

Para reemplazar una línea, puede usar los comandos c (cambiar) o s (sustituir) con una dirección numérica:

$ seq 3|sed $''2c///n1.5/n'' 1 1.5 3 $ seq 3|gsed ''2c1.5'' 1 1.5 3 $ seq 3|sed ''2s/.*/1.5/'' 1 1.5 3

Alternativas usando awk :

$ seq 3|awk ''NR==2{print 1.5}1'' 1 1.5 2 3 $ seq 3|awk ''{print NR==2?1.5:$0}'' 1 1.5 3

awk interpreta barras invertidas en variables pasadas con -v pero no en variables pasadas usando ENVIRON :

$ seq 3|awk -v v=''a/ba'' ''{print NR==2?v:$0}'' 1 a 3 $ seq 3|v=''a/ba'' awk ''{print NR==2?ENVIRON["v"]:$0}'' 1 a/ba 3

Tanto ENVIRON como -v están definidos por POSIX.


Para aquellos que están en SunOS que no es GNU, el siguiente código ayudará:

sed ''1i/^J line to add'' test.dat > tmp.dat

  • ^ J se inserta con ^ V + ^ J
  • Agregue la nueva línea después de ''1i.
  • / DEBE ser el último personaje de la línea.
  • La segunda parte del comando debe estar en una segunda línea.

Soluciones de Perl:

rápido y sucio:

perl -lpe ''print "Project_Name=sowstest" if $. == 8'' file

  • -l quita las nuevas líneas y las agrega nuevamente, eliminando la necesidad de "/ n"
  • -p bucles sobre el archivo de entrada, imprimiendo cada línea
  • -e ejecuta el código entre comillas simples

$. es el número de línea

equivalente a la solución awk de @glenn, usando argumentos con nombre:

perl -slpe ''print $s if $. == $n'' -- -n=8 -s="Project_Name=sowstest" file

  • -s permite un analizador de argumentos rudimentario
  • -- previene que el analizador de argumentos perl estándar analice -n y -s

argumentos de comando de posición:

perl -lpe ''BEGIN{$n=shift; $s=shift}; print $s if $. == $n'' 8 "Project_Name=sowstest" file

Variables de entorno:

setenv n 8 ; setenv s "Project_Name=sowstest" echo $n ; echo $s perl -slpe ''print $ENV{s} if $. == $ENV{n}'' file

ENV es el hash que contiene todas las variables de entorno

Getopt para analizar argumentos en hash% o:

perl -MGetopt::Std -lpe ''BEGIN{getopt("ns",/%o)}; print $o{s} if $. == $o{n}'' -- -n 8 -s "Project_Name=sowstest" file

Getopt :: Nombres de opciones largas y largas

perl -MGetopt::Long -lpe ''BEGIN{GetOptions(/%o,"line=i","string=s")}; print $o{string} if $. == $o{line}'' -- --line 8 --string "Project_Name=sowstest" file

Getopt es la solución de biblioteca estándar recomendada.
Esto puede ser excesivo para los scripts de Perl de una línea, pero se puede hacer


Una respuesta ed

ed file << END 8i Project_Name=sowstest . w q END

. en su propia línea finaliza el modo de entrada; w escribe; q GNU ed tiene un comando wq para guardar y salir, pero los ed antiguos no.

Lectura adicional: https://gnu.org/software/ed/manual/ed_manual.html


la respuesta awk

awk -v n=8 -v s="Project_Name=sowstest" ''NR == n {print s} {print}'' file > file.new


sed -e ''8iProject_Name=sowstest'' -i start usar GNU sed

Muestra de ejecución:

[root@node23 ~]# for ((i=1; i<=10; i++)); do echo "Line #$i"; done > a_file [root@node23 ~]# cat a_file Line #1 Line #2 Line #3 Line #4 Line #5 Line #6 Line #7 Line #8 Line #9 Line #10 [root@node23 ~]# sed -e ''3ixxx inserted line xxx'' -i a_file [root@node23 ~]# cat -An a_file 1 Line #1$ 2 Line #2$ 3 xxx inserted line xxx$ 4 Line #3$ 5 Line #4$ 6 Line #5$ 7 Line #6$ 8 Line #7$ 9 Line #8$ 10 Line #9$ 11 Line #10$ [root@node23 ~]# [root@node23 ~]# sed -e ''5ixxx (inserted) "line" xxx'' -i a_file [root@node23 ~]# cat -n a_file 1 Line #1 2 Line #2 3 xxx inserted line xxx 4 Line #3 5 xxx (inserted) "line" xxx 6 Line #4 7 Line #5 8 Line #6 9 Line #7 10 Line #8 11 Line #9 12 Line #10 [root@node23 ~]#


sed -i ''8i8 This is Line 8'' FILE

inserciones en la línea 8

8 This is Line 8

en archivo FILE

-i hace la modificación directamente al archivo FILE, sin salida a stdout, como se menciona en los comentarios de glenn jackman.