2011-06-06 15 views
12

sin preámbulos,¿Cómo funciona el comando 'N' en sed?

 
$ cat in.txt 
a 
b 
c 
d 
$ sed '=;N' in.txt 
1 
a 
b 
3 
c 
d 

Parece que funciona el comando 'N' en cada línea. Quizás eso sea natural, porque el comando 'N' se une a la línea siguiente y cambia el número de línea actual. Pero,

 
$ sed 'N;$!P;$!D;$d' thegeekstuff.txt 

(vi este here)
anterior ejemplo se elimina dos últimas líneas de un fichero. Esto no solo funciona con el archivo de línea par, sino también con el archivo de número impar. Entonces en este ejemplo, el comando 'N' se ejecuta en cada línea.
¿Cuál es la diferencia?

¿Y podría decirme por qué no puedo ver la última línea cuando ejecuto sed de esta manera?

 
# sed N odd-lined-file.txt 

Respuesta

19

Extracto de info sed:

`sed' operates by performing the following cycle on each lines of 
input: first, `sed' reads one line from the input stream, removes any 
trailing newline, and places it in the pattern space. Then commands 
are executed; each command can have an address associated to it: 
addresses are a kind of condition code, and a command is only executed 
if the condition is verified before the command is to be executed. 
... 
When the end of the script is reached, unless the `-n' option is in 
use, the contents of pattern space are printed out to the output 
stream, 
... 
Unless special commands (like 'D') are used, the pattern space is 
deleted between two cycles 

... 

`N' 
    Add a newline to the pattern space, then append the next line of 
    input to the pattern space. If there is no more input then `sed' 
    exits without processing any more commands. 

... 

`D' 
    Delete text in the pattern space up to the first newline. If any 
    text is left, restart cycle with the resultant pattern space 
    (without reading a new line of input), otherwise start a normal 
    new cycle. 

Esto debería resolver más o menos con la consulta. Pero aún así voy a tratar de explicar sus tres casos diferentes:

CASO 1:

  1. sed lee una línea de entrada. [Ahora hay 1 línea en el espacio del patrón.]
  2. = Imprime la línea actual no.
  3. N lee la siguiente línea en el espacio del patrón. [Ahora hay 2 líneas en el espacio del patrón.]
    • Si no hay una nueva línea para leer, sed sale aquí. [ie: en el caso de las líneas impares, sed exits aquí - y por lo tanto, la última línea se traga sin imprimir.]
  4. sed imprime el espacio del patrón y lo limpia. [El espacio del patrón está vacío.]
  5. Si EOF llegó a sed sale aquí. Else Reinicie el ciclo completo desde el paso 1. [ie: en el caso de líneas pares, sed sale aquí.]

Resumen: En este caso sed lee 2 líneas e imprime 2 líneas a la vez. La última línea es tragada, hay líneas impares (ver paso 3).

CASO 2:

  1. sed lee una línea de entrada. [Ahora hay 1 línea en el espacio del patrón.]
  2. N lee la siguiente línea en el espacio del patrón. [Ahora hay 2 líneas en el espacio del patrón.]
    • Si falla, salga de aquí. Esto ocurre solo si hay 1 línea.
  3. Si no es la última línea ($!) imprime la primera línea (P) del espacio de patrones. [Se imprime la primera línea del espacio del patrón. Pero aún hay 2 líneas en el espacio del patrón.]
  4. Si no es la última línea ($!) elimine la primera línea (D) del espacio del patrón [Ahora solo hay 1 línea (la segunda) en el espacio del patrón.] y reiniciar el ciclo de comando desde el paso 2. Y es debido al comando D(ver el extracto anterior).
  5. Si su última línea ($) borre (d) el espacio de patrón completo. [es decir. llegó a EOF] [Antes de comenzar este paso, había 2 líneas en el espacio del patrón que ahora se limpian con d - al final de este paso, el espacio del patrón está vacío.]
  6. sed se detiene automáticamente en EOF.

Resumen: En este caso:

  • sed lee 2 líneas primera.
  • si hay una nueva línea disponible para leer, imprima la primera línea y lea la siguiente línea.
  • else eliminan ambas líneas de la memoria caché. De esta manera siempre borra las 2 últimas líneas.

CASO 3:
Su el mismo caso que CASO: 1, simplemente retire el Paso 2 de la misma.

+0

bueno, no puedo entender esto a fondo. Esto significa que el comando 'N' se ejecutará en cada línea si solo el espacio del patrón no está vacío. y ejecutar cada dos líneas cuando el espacio del patrón está vacío? – plhn

+1

Considerando su comentario, he actualizado la respuesta. Por favor, verifíquelo una vez. – ssapkota

+0

Muchas gracias !!!!!!!! – plhn

Cuestiones relacionadas