
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 --unique
algumas 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 ls
a 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))