Encuentre elementos comunes/patrones en un montón de archivos

Encuentre elementos comunes/patrones en un montón de archivos

Digamos que tengo una carpeta con cientos o miles de archivos, todos con el nombre del siguiente esquema:

<random number of variable length>_<date code in YYYYMMDD format>.jpg

Ejemplo:

73923_20180927.jpg
4457582_20180927.jpg
   ...
18733557_20190401.jpg
23573_20190401.jpg
   ...

Lo que espero que haga mi script bash es imprimir una lista de esos códigos de fecha, es decir

20180927
20190401
   ...

Parece una tarea más fácil. Dado que el esquema es siempre el mismo, ya logré aplicar la manipulación de cadenas para imprimir solo la parte requerida de los nombres de los archivos. Sin embargo, todavía estoy averiguando cómo imprimir cada fecha solo una vez.

¿Existe una manera clara de salir de esto?

Respuesta1

Suponiendo que todos los nombres de archivos coincidan con el patrón ./*_*.jpg:

for name in ./*_*.jpg; do
    name=${name##*_}              # 4457582_20180927.jpg --> 20180927.jpg
    printf '%s\n' "${name%.jpg}"  # 20180927.jpg --> 20180927
done | sort -u

Esto itera sobre todos los nombres. Para cada nombre, elimina la cadena de prefijo más larga que coincida *_. Luego genera la cadena restante sin el .jpgsufijo.

Luego, todas las cadenas se ordenan de tal manera que al final solo se genera una lista de cadenas únicas.

Si existe el riesgo de que el directorio esté vacío, debe configurar la nullglobopción de shell antes del bucle ( shopt -s nullglob). Esto haría que el bucle no se ejecutara en absoluto en lugar de ejecutarse una vez con el patrón global no expandido en $name.


Sin ningún motivo en particular, así es como se hace sin sort:

declare -A skip=()

for name in ./*_*.jpg; do
    key=${name##*_}    # 4457582_20180927.jpg --> 20180927.jpg
    key=${key%.jpg}    # 20180927.jpg --> 20180927
    if [[ ! -v skip[$key] ]]; then
        printf '%s\n' "$key"
        skip[$key]=1
    fi
done

Aquí, hago un seguimiento de las cadenas que ya se han generado como claves en una matriz asociativa skip. No se generará una cadena si corresponde a una clave de la matriz.

Respuesta2

Suponiendo que realmente no haya nombres de archivos incorrectos, ejecute en ese directorio:

ls -U | awk '-F[_.]' '{ print $2 }' | sort | uniq

información relacionada