¿Qué hay de usando awk
? Usted puede obtener la primera aparición muy simple:
[[email protected] ~]$ cat data1
./501.res/1.bin
./503.res/1.bin
./503.res/2.bin
./504.res/1.bin
[[email protected] ~]$ awk 'BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1' data1
./501.res/1.bin
./503.res/1.bin
./504.res/1.bin
[[email protected] ~]$
para conseguir la última ocurrencia que pudiera tubería a través de un par de clases:
[[email protected] ~]$ sort -r data1 | awk 'BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1' | sort
./501.res/1.bin
./503.res/2.bin
./504.res/1.bin
[[email protected] ~]$
Dado que usted está utilizando "encontrar" y "grep" , que probablemente podría hacer esto:
find . -name \*.bin -type f -print | sort -r | awk 'BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1' | sort
¿Cómo funciona esto?
El comando find
tiene muchas opciones útiles, incluyendo la capacidad de seleccionar los archivos por glob, seleccione el tipo de archivo, etc. Su salida que ya conoce, y que se convierte en la entrada a sort -r
.
Primero, ordenamos nuestros datos de entrada en reversa (sort -r
). Esto asegura que dentro de cualquier directorio, el archivo con el número más alto aparecerá primero. Ese resultado se alimenta en awk. FS es el separador de campo, que hace $2
en cosas como "/ 501", "/ 502", etc. Las secuencias de comandos Awk tienen secciones en forma de condition {action}
que se evalúan para cada línea de entrada. Si falta una condición, la acción se ejecuta en cada línea. Si "1" es la condición y no hay acción, imprime la línea. Así que este guión se divide de la siguiente manera:
a[$2] {next}
- Si la matriz a
con el subíndice $ 2 (es decir "/ 501") existe, acaba de saltar a la siguiente línea. De lo contrario ...
{a[$2]=1}
- Colocar el conjunto un subíndice $ 2 a 1, por lo que en el futuro la primera condición se evaluará como cierto, entonces ...
1
- imprimir la línea.
La salida de este script awk será la información que desee, pero en orden inverso. El sort
final pone las cosas en el orden que esperabas.
Ahora ... eso es un montón de tuberías, y la ordenación puede ser un poco hambrienta de recursos cuando le pides que trate millones de líneas de entrada al mismo tiempo. Esta solución será perfectamente suficiente para pequeñas cantidades de archivos, pero si está tratando con grandes cantidades de información, infórmenos, y puedo encontrar una solución awk todo en uno (que llevará más de 60 segundos). escribir).
ACTUALIZACIÓN
sabio consejo
por Dennis', el script awk Incluí anterior podría mejorarse cambiando desde
BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1
a
BEGIN{FS="."} $2 in a {next} {a[$2]} 1
Si bien esto es funcionalmente idéntica , la ventaja es que usted simplemente define los miembros de la matriz en lugar de asignarles valores, lo que puede ahorrar memoria o CPU. pendiente de su implementación de awk. En cualquier caso, es más limpio.
Es mejor probar la existencia de un elemento en una matriz usando '$ 2 en a {next}'. Hacerlo de esa manera no crea nuevos elementos de matriz simplemente al referirse a ellos. Esto es lo que quise decir el otro día cuando discutíamos esto. Por cierto, si usa 'in' de esa manera, puede hacer' {a [$ 2]} 'en lugar de' {a [$ 2] = 1} ', pero cualquiera de los dos funcionará. –
@DennisWilliamson, AH, ahora entiendo lo que estabas recibiendo el otro día. Muchas gracias por el puntero. :) – ghoti