Enumere solo archivos únicos según el nombre de archivo parcial

Enumere solo archivos únicos según el nombre de archivo parcial

Por ejemplo, tengo muchos archivos que se parecen al resultado siguiente. Estoy intentando obtener una lista de todos los nombres de archivos únicos, pero ignoro los caracteres a la derecha del "-". Lo he intentado ls -la | grep ....- | sort --uniquey algunas variaciones pero eso no da el resultado que necesito.

4855-00160880.psi
4855-00160980.ps
4855-00160980.psi
5355-00160880.ps
5355-00160880.psi
5355-00160980.ps
5355-00160980.psi
5855-00160880.ps
5855-00160880.psi
5855-00160980.ps
5855-00160980.psi
5855-00160A80.ps
5855-00160A80.psi

Idealmente me gustaría que el resultado mostrara algo como

4855
5355
5855

Respuesta1

Desderealmente no quieres analizarls, Esto debería funcionar:

find . -type f -maxdepth 1 -exec basename "{}" \; | cut -d'-' -f1 | sort -u

Respuesta2

¿Cómo es esto?

printf "%-4.4s\n" ????-* | uniq

El shell expande el comodín en orden alfabético y pasa el resultado como argumentos a printf. La cadena de formato trunca cada argumento a cuatro caracteres y agrega una nueva línea. Ahora solo queda eliminar los duplicados adyacentes.

Si no conoce el número de dígitos antes del guión, pero tiene una idea, puede recorrer algunos candidatos:

for expr in '??' '???' '????' '?????'  # Quoted (!)
do
    printf "%-${#expr}.${#expr}\n" $expr-* |  # Unquoted!
    uniq
done

Esto usa solo Bashexpansión de parámetros $[#var}que obtiene la longitud de la cadena de $var.

Observe el truco de citar los comodines para evitar su expansión en la inicialización del bucle y luego usar la variable sin comillas dentro del bucle (lo cual es un no-no en la mayoría de los demás casos).

Respuesta3

Vale la pena agregarlo -type fa la respuesta de DopeGhoti, para evitar ese .resultado falso.

find . -maxdepth 1 -exec basename "{}" \; | cut -d'-' -f1 | sort -u
.
4855
5355
5855
find . -maxdepth 1 -type f -exec basename "{}" \; | cut -d'-' -f1 | sort -u
4855
5355
5855
$

Si desea mantener algo similar a su intento original, puede usar esto (¡mal, aunque se analiza ls!)

ls -1 | grep ^....-  | cut -c1-4 | sort --unique

solución basada en awk, todavía analizando ls

ls -1 | awk -F- '{print $1}' | sort --unique

No es necesario ordenar en cada uno de estos casos, ya que lsla salida ya está ordenada, por lo que simplemente se puede usar uniq.

ls -1 | awk -F- '{print $1}' | uniq

solución basada en sed

ls -1 | sed 's/-.*//' | uniq

encontrar / sed solución que evita el análisis de ls

find . -type f -printf "%f\n" | sed 's/-.*//g' | sort --unique

Si siempre hay 4 dígitos antes del "-", entonces esto es bastante elegante

find . -type f -printf "%.4f\n" | sort -u

Respuesta4

Con zsh:

myfiles=(*-*(.))
print -rl -- ${(u)myfiles[@]%%-*}

Esto guarda todos los nombres de archivos normales que contienen al menos un guión en una matriz. Luego utiliza la expansión de parámetros en cada elemento de la matriz para eliminar el primer guión y todo lo que sigue. Cualquier elemento duplicado se elimina mediante la (u)bandera.
Para seleccionar archivos ocultos también, usemyfiles=(*-*(.D))

información relacionada