¿Cómo puedo escribir en la segunda línea de un archivo desde la línea de comandos?

29

Tengo un programa externo que produce un archivo de salida (grande, 20K líneas posibles).

Necesito insertar una nueva línea entre la línea existente 1 y la línea 2. He estado mirando awk y sed - uso uno de los revestimientos en cada uno con bastante regularidad - pero no he podido encontrar los interruptores correctos para hacer esto.

Tim Brigham
fuente

Respuestas:

20
awk 'NR==1{print; print "new line"} NR!=1'
Kevin
fuente
12
Un poco más corto:awk 'NR==2 {print "new line"} 1'
Glenn Jackman el
@glennjackman: su versión no funciona en mi sistema, pero la respuesta sí. Específicamente, con la suya, la línea 2 se duplica y la nueva línea se inserta entre ambas (como la línea 3).
Nikana Reklawyks
¿Hay alguna manera de comenzar a escribir en la segunda línea y sobrescribir todas las líneas siguientes?
CMCDragonkai
@ CMCDragonkai No estoy muy seguro de lo que estás pidiendo. ¿Solo imprime la primera línea del archivo especificado y una segunda línea establecida? Primera línea y luego el contenido de un archivo? ¿La primera línea del primer archivo y luego una línea de un segundo archivo para cada línea restante en la primera? Es posible que desee hacer una nueva pregunta con una descripción muy específica de lo que desea y un ejemplo relativamente corto pero completo.
Kevin
16

Para su caso específico, esto debería ser más simple:

sed '1 { P ; x }' your-file

Explicación: en la línea 1 , haga lo siguiente

  1. P rint la línea
  2. E x cambia el espacio del patrón con el espacio de retención (básicamente vacía el búfer)

Luego, la línea (vacía ahora) se imprime nuevamente como parte del ciclo.


Si desea agregar una nueva línea en lugar de un nuevo carácter de línea (lo que entendí inicialmente), entonces simplemente use sedel comando a\(agregar):

sed '1 a\
appended line' your-file

o incluso

sed '1 aappended line' your-file

Anexa " appended line" después de la línea 1.

angus
fuente
1
sed -i '1 a\\' filepor solo una nueva línea.
forcefsck
1
@forcefsck Sí, la única desventaja es que es un GNUismo, como mi segundo '1 aapended line'ejemplo.
angus
8

Supongo que el sedenfoque sería:

sed '2 i whatever_line_of_text_you_wanted_to_INSERT' filename.txt

Esto llevará el texto a la segunda línea del archivo y luego la segunda línea real en el archivo se convertirá en la tercera.

Tenga en cuenta que, si usa el modo agregar , si tenía que ser así, tenía que usar la primera línea, ya que la adición ocurrirá después del número de línea anotado.

sed '1 a whatever_line_of_text_you_wanted_to_INSERT' filename.txt

Nikhil Mulley
fuente
2

Esto podría funcionar para usted:

sed 1G file

Si desea insertar somethingdespués de la nueva línea:

sed '1{G;s/$/something/}' file

O si sed maneja \n:

sed '1s/$/\nsomething/' file

Por supuesto aes aún más fácil:

sed '1a something' file
potong
fuente
Lo siento, ¿qué hace?
Nikhil Mulley
Inserta una nueva línea después de la línea 1
potong
1
¡O más bien agrega una nueva \nlínea a la línea uno!
potong
1

Usualmente uso edpara esto:

(echo 1a; echo 'Line to insert'; echo .; echo w) | ed - filename

Similar a una sedsolución, pero sin el desorden de las nuevas líneas escapadas.

Arcege
fuente
2
Se podría prescindir de algunos echo's, especialmente bajo bash: ed - filename <<< $'1a\nLine to insert\n.\nw'.
manatwork
1
No funciona en todos los shells, por ejemplo dash, en muchos sistemas /bin/sh.
Arcege
1
Por eso escribí "Podrías ahorrar algunas echo ". Ahorradores de toda echo 's es de hecho bashúnica característica, pero reduciendo el echorecuento de 4 a 1 en las obras dashy kshtambién: echo '1a\nLine to insert\n.\nw' | ed - filename.
manatwork
1
O simplemente useprintf %s\\n , que coloca una nueva línea después de cada argumento que le da y no arruina los caracteres especiales incrustados en la línea que desea insertar. Además, ¿por qué usarlo edcuando exestá disponible?
Comodín el
1

Solución Python

python -c "import sys; lines = sys.stdin.readlines(); lines.insert(1,'New Line\n'); print ''.join(lines).strip()" < input.txt
Rahul Patil
fuente
0

Uso de sedcódigos de escape ANSI (específicos de Bash):

# note: \ --> \\
printf '%s\n' 1 2 3 4 5 | sed -e $'1 { s/\\(.*\\)/\\1\\\ninserted line/; }'
topi
fuente
0

usaría Python para esto

import fileinput

for linenum,line in enumerate(fileinput,FileInput("file",inplace=1)):
    if linenum ==1:
          print ""
          print line.rstrip() 
      else: 
          print line.rstrip()`
harish.venkat
fuente
0

Simplemente me gusta usar un contador explícito:

awk '(c==1) {print "new line"} (c!=1) {print $0} {c++}' file
Profesor Awk
fuente
0

El método más simple utiliza printfy ex:

printf '%s\n' 1a 'my line to insert' . x | ex file

1asignifica "agregar después de la primera línea"; el .final del anexo; xsignifica guardar y salir.

Comodín
fuente
0

Ninguna de las respuestas anteriores menciona cómo guardar los cambios en el archivo original, que es lo que el OP estaba pidiendo.

Sin duda es lo que necesitaba cuando camé a la página.

Asumiendo que su archivo se llama output.txt

sed -i '1 a This is the second line' output.txt

Mi caso de uso particular es agregar automáticamente una declaración de hoja de estilo xsl a un archivo xml junit.

sed -i '1 a <?xml-stylesheet type="text/xsl" href="junit-html.xsl"?>' junit.xml
chim
fuente
yourownlinux.com/2015/04/… es la parte relevante de una introducción bien escrita a sed.
chim