2012-07-28 15 views
8

Tengo un archivo de entrada que se ve así (la primera columna es un número de ubicación y la segunda es un conteo que debe aumentar con el tiempo) :awk solución para comparar línea actual con línea siguiente e imprimir una de las líneas según una condición

1  0 
1  2 
1  6 
1  7 
1  7 
1  8 
1  7 
1  7 
1  9 
1  9 
1  10 
1  10 
1  9 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  9 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 

y me gustaría fijar que se vea como esto (los recuentos de sustitutos que disminuyeron con el recuento anterior):

1  0 
1  2 
1  6 
1  7 
1  7 
1  8 
1  8 
1  8 
1  9 
1  9 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 

he estado tratando de usar awk para esto, pero am tropezando con getline ya que no puedo encontrar la forma de restablecer el número de línea (NR?) para que sea r ead cada línea y es la siguiente línea, no dos líneas a la vez. Este es el código que tengo hasta ahora, ¿alguna idea?

awk '{a=$1; b=$2; getline; c=$1; d=$2; if (a==c && b<=d) print a"\t"b; else print c"\t"d}' original.txt > fixed.txt 

Además, esta es la salida actualmente estoy recibiendo:

1  0 
1  6 
1  7 
1  7 
1  9 
1  10 
1  9 
1  10 
1  10 
1  9 
1  10 
1  10 
1  10 
+0

Ok, solo para aclarar, ¿estás tratando de * omitir * las líneas donde el conteo disminuye? Esas son muchas líneas, me pregunto si podrías dar un ejemplo más breve que sería igual de claro. – Levon

+0

Lo siento si mi explicación no era clara, quiero imprimir la línea anterior cuando el conteo disminuye, así que termine con el mismo número de líneas pero con un archivo donde el conteo se mantiene o aumenta, pero nunca disminuye. – suegene

+0

Lo tengo ... mira las respuestas que se proporcionan a continuación, creo que encontrarás lo que estás buscando. – Levon

Respuesta

7

Tal vez lo que desea es:

awk '$2 < p { $2 = p } { p = $2 } 1' input-file 

Esto se producirá un error en la primera línea si el valor de la segunda columna es negativa, también lo hace:

awk 'NR > 1 && $2 < p ...' 

Esto simplemente establece la segunda columna al valor anterior si el valor actual es menor, luego almacena el valor actual en la variable p, luego imprime la línea.

Tenga en cuenta que esto también modifica ligeramente el espaciado de la salida en las líneas que cambian. Si la entrada es separado por tabuladores, es posible que desee hacer:

awk 'NR > 1 && $2 < p { $2 = p } { p = $2 } 1' OFS=\\t input-file 
+0

Wow ... mucho más conciso ... Creo que tengo la versión detallada de su primera solución – Levon

+0

¡Fantástico, solo estaba tratando de calcular el espaciado, gracias! – suegene

2

Este script va a hacer lo que te gusta:

{ 
    if ($2 < prev_count) 
    $2 = prev_count 
    else 
    prev_count = $2 

    printf("%d %d\n", $1, $2) 
} 

Ésta es una versión detallada para ser fácilmente legibles :)

+0

¡Gracias, aprecio la versión detallada también! – suegene

+0

@suegene Feliz de ayudar ... Ajusté el espaciado de salida con 'printf', que puede darle un control un poco más fino sobre el formato/espaciado si lo necesita. – Levon

Cuestiones relacionadas