
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 --unique
y 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 f
a 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 ls
la 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))