Liste apenas arquivos exclusivos com base no nome do arquivo parcial

Liste apenas arquivos exclusivos com base no nome do arquivo parcial

Por exemplo, tenho muitos arquivos parecidos com a saída abaixo. Estou tentando obter uma lista de todos os nomes de arquivos exclusivos, mas desconsidero os caracteres à direita do "-". Eu tentei ls -la | grep ....- | sort --uniquealgumas variações, mas isso não dá o resultado que preciso

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, eu gostaria que a saída mostrasse algo como

4855
5355
5855

Responder1

Desdevocê realmente não quer analisarls, isso deve funcionar:

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

Responder2

Como é isso?

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

O shell expande o curinga em ordem alfabética e passa o resultado como argumentos para printf. A string de formato trunca cada argumento em quatro caracteres e adiciona uma nova linha. Agora só falta remover as duplicatas adjacentes.

Se você não sabe o número de dígitos antes do hífen, mas tem uma ideia, pode percorrer alguns candidatos:

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

Isso usa apenas o Bashexpansão de parâmetros $[#var}que obtém o comprimento da string de $var.

Observe o truque de citar os curingas para evitar sua expansão na inicialização do loop e, em seguida, usar a variável sem aspas dentro do loop (o que é proibido na maioria dos outros casos).

Responder3

Vale a pena acrescentar -type fà resposta do DopeGhoti, para evitar esse .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
$

Se desejar manter semelhante à sua tentativa original, você pode usar isto (ruim, pois analisa ls!)

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

solução baseada em awk, ainda analisando ls

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

Não há necessidade real de classificar em cada um desses casos, pois lsa saída já está classificada, portanto, basta usar uniq.

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

solução baseada em sed

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

solução find/sed que evita a análise de ls

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

Se sempre 4 dígitos antes do "-" então isso é bastante elegante

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

Responder4

Com zsh:

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

Isso salva todos os nomes de arquivos regulares que contêm pelo menos um traço em uma matriz. Em seguida, ele usa a expansão de parâmetros em cada elemento da matriz para remover o primeiro traço e tudo o que vem a seguir. Quaisquer elementos duplicados são removidos por meio do (u)sinalizador.
Para selecionar arquivos ocultos também, usemyfiles=(*-*(.D))

informação relacionada