2012-04-10 15 views
5

Estoy tratando de leer un archivo y ordenarlo por el número de apariciones de un campo en particular. Supongamos que quiero encontrar la fecha más repetida de un archivo de registro, entonces uso la opción uniq -c y la ordenamos en orden descendente. algo como estoNecesito eliminar el recuento de la salida al usar el comando "uniq -c"

uniq -c | sort -nr 

Esto producirá alguna salida como esta -

809 23/Dec/2008:19:20 

el primer campo que es en realidad la cuenta es el problema para mí .... quiero conseguir ony la fecha a partir la salida anterior, pero m no puede obtener esto. He intentado utilizar el comando de corte y lo hizo

uniq -c | sort -nr | cut -d' ' -f2 

pero esto sólo imprime espacio en blanco ... Por favor alguien me puede ayudar en conseguir sólo la fecha y cortar el recuento. Quiero sólo

23/Dec/2008:19:20 

Gracias

+0

¿está seguro de que su salida se ve así? Intenté 'echo '809 23/Dic/2008: 19: 20' | cut -d '' -f2' y funciona bien – Anirudh

+1

Dependiendo de la implementación de 'uniq' en uso, puede haber cero o más espacios antes del recuento de repetición '809'. Sin espacios en blanco iniciales, la expresión original funcionaría bien. Debido a que algunas implementaciones de 'uniq -c' producen espacios en blanco iniciales, tiene problemas. –

+0

Jonathan ... fue una suposición perfecta ... veo que hay un espacio en blanco antes del conteo. – ravi

Respuesta

8

El recuento de uniq está precedida por espacios a menos que haya más de 7 dígitos en el recuento, por lo que necesita para hacer algo como:

uniq -c | sort -nr | cut -c 9- 

a obtener columnas (posiciones de caracteres) 9 hacia arriba. O puede utilizar sed:

uniq -c | sort -nr | sed 's/^.\{8\}//' 

o:

uniq -c | sort -nr | sed 's/^ *[0-9]* //' 

Esta segunda opción es robusto frente a la cantidad de repeticiones de 10 millones o más; Si crees que eso podría ser un problema, probablemente sea mejor que la alternativa cut. Y sin duda hay otras opciones disponibles también.


Advertencia: los recuentos se determinaron mediante experimentación en Mac OS X 10.7.3, pero utilizando GNU uniq de coreutils 8.3. El BSD uniq -c produjo 3 espacios iniciales antes de contar un solo dígito. La especificación POSIX dice que la salida de uniq -c se formatea como si con:

printf("%d %s", repeat_count, line); 

que no tendría ningún espacios a la izquierda.Teniendo en cuenta esta posible variación en los formatos de salida, el guión sed con el [0-9] expresión regular es la forma más confiable de hacer frente a la variabilidad de la producción observada y teórica de uniq -c:

uniq -c | sort -nr | sed 's/^ *[0-9]* //' 
+0

Gracias ... me ayudó mucho y aprendí un nuevo comando sed. Todavía soy nuevo en este shell scripting. – ravi

4

En lugar de cut -d' ' -f2, tratan

awk '{$1="";print}' 

Quizás tiene que quitar una más sin grabar al principio:

awk '{$1="";print}' | sed 's/^.//' 

o completamente con sed, preservando whitspace el original:

sed -r 's/^[^0-9]*[0-9]+//' 
+0

Muchas gracias ... ayudó – ravi

+0

Niza: solución genérica, independiente de la versión OS y 'uniq'. – Sim

1

una solución alternativa es la siguiente:

uniq -c | sort -nr | awk '{print $1, $2}' 

también se puede imprimir fácilmente un solo campo.

+0

Esto solo funciona si el segundo campo no contiene espacios en blanco. – tripleee

1

Si desea trabajar con el campo de cuenta corriente abajo, siguiente comando formatear a un 'amistoso tubería' formato delimitado pestaña sin el relleno a la izquierda:

.. | sort | uniq -c | sed -r 's/^ +([0-9]+) /\1\t/' 

Para la tarea original que es un poco de una exageración, pero después de formato, cut se puede utilizar para eliminar el campo, como se pretende OP:

.. | sort | uniq -c | sed -r 's/^ +([0-9]+) /\1\t/' | cut -d $'\t' -f2- 
1

Añadir tr -s a la cadena de tubería a "exprimir" varios espacios por un delimitador de espacio:

uniq -c | tr -s ' ' | cut -d ' ' -f3 

tr es muy útil en algunos lugares oscuros. Desafortunadamente no se deshace del primer espacio principal, de ahí que el -f3

Cuestiones relacionadas