2010-08-03 12 views
5

Digamos que tiene lo siguiente.¿Cómo agruparías varias líneas?

192.168.0.100 
192.168.0.100 
192.168.0.100 
192.168.0.102 
192.168.0.102 
192.168.0.100 

Eso se considera 3 éxitos únicos. La forma de distinguirlo es que las IP idénticas consecutivas cuentan como una. ¿Cómo recorrerá el archivo y contará en consecuencia?

+0

Tal vez hacerlo en dos pasos: primero pasar y fusionar las direcciones IP consecutivas, y luego contar todas las líneas en el archivo? –

+1

posible duplicado de [La mejor forma de simular "agrupar por" desde bash] (http://stackoverflow.com/questions/380817/best-way-to-simulate-group-by-from-bash) –

+2

¿Qué significa? "en bash" exactamente? eliminar duplicados consecutivos es el trabajo de "uniq", así que para resolver el problema, un "cat data | uniq | wc -l" debería cortarlo ... ¿pero es "bash"? – 6502

Respuesta

10

Si su uniq es como el mío, y funciona sólo cadenas similares en secuencia, simplemente no ordenar antes de uniq:

archivo foo.txt:

192.168.0.100 
192.168.0.100 
192.168.0.100 
192.168.0.102 
192.168.0.102 
192.168.0.100 

Y:

$ cat foo.txt | uniq -c 

editar: ¿puedo otorgarme un premio useless use of cat?

$ uniq -c foo.txt 

/editar
Salida:

3 192.168.0.100 
    2 192.168.0.102 
    1 192.168.0.100 
+0

Esto funciona, lo ordené antes del conteo de líneas. – luckytaxi

1

No estoy familiarizado con las secuencias de comandos bash, pero la idea sería realizar un seguimiento de la IP marcada anterior. Entonces, si anterior == actual, no incremente, ¿aumentará?

+1

+1: Esta sería una forma sencilla de hacerlo. –

3

Evitaría usar bash para esto. Use un lenguaje real como Python, awk o incluso Perl.

Python

#!/usr/bin/env python 
from __future__ import print_function 
import fileinput 
def combine(source): 
    count, prev= 1, source.next() 
    for line in source: 
     if line == prev: 
      count += 1 
     else: 
      yield count, prev 
      count, prev = 1, line 
    yield count, prev 
for count, text in combine(fileinput.input()): 
    print(count, text) 

simple y extremadamente rápido en comparación con bash.

Dado que esto se lee de stdin y escribe en stdout, puede usarlo como un comando simple en una interconexión.

+0

Elegante, pero no estoy seguro de que resuelva el problema del OP.El conjunto de datos anterior debe devolver tres grupos en el mapa, no dos. My Python no es muy bueno, pero a primera vista diría que devolvería dos grupos. –

+0

Si tiene dos entradas para la misma IP, con otra IP intermedia, ¿contará esto correctamente? Creo que debes discriminar entre la 1ª, la 2ª, la enésima ocurrencia de la misma IP, siempre que no sean consecutivas. Además, especifique qué versión de Python está utilizando, quizás con un shebang en la parte superior. –

+0

@Hamish Grubijan: Esto funcionará con cualquier versión que incluya collections.defaultdict. Eso es> = 2.5. –

0

similares a @ respuesta de Wrikken, pero yo creo que usted quiere recuentos totales:

Si el archivo que contiene los datos anteriores es foo. txt, luego:

$ cat foo.txt | uniq | wc -l 
3 

Que es lo que quieres, creo.

Cuestiones relacionadas