Diga ao `ls` para imprimir apenas o nome do arquivo base

21

Esse é o comportamento padrão de ls

ls /net/nas/data/languages/pypm/sites/rex/free/2.6/*/pool/v/vi/virtual*1.4.4*pypm
/net/nas/data/languages/pypm/sites/rex/free/2.6/linux-x86/pool/v/vi/virtualenv-1.4.4_linux-x86_2.6_1.pypm
/net/nas/data/languages/pypm/sites/rex/free/2.6/linux-x86_64/pool/v/vi/virtualenv-1.4.4_linux-x86_64_2.6_1.pypm
/net/nas/data/languages/pypm/sites/rex/free/2.6/macosx/pool/v/vi/virtualenv-1.4.4_macosx_2.6_1.pypm
/net/nas/data/languages/pypm/sites/rex/free/2.6/win32-x86/pool/v/vi/virtualenv-1.4.4_win32-x86_2.6_1.pypm

Como faço para lsimprimir apenas o nome da base? Gostar:

ls $OPTIONS /net/nas/data/languages/pypm/sites/rex/free/2.6/*/pool/v/vi/virtual*1.4.4*pypm
virtualenv-1.4.4_linux-x86_2.6_1.pypm
virtualenv-1.4.4_linux-x86_64_2.6_1.pypm
virtualenv-1.4.4_macosx_2.6_1.pypm
virtualenv-1.4.4_win32-x86_2.6_1.pypm

Nota : Prefiro o shell globbing do que usar findcomo / net / nas / data / languages ​​/ pypm / sites / rex / free contém um grande número de arquivos e diretórios.

Srid diz Restabelecer Monica
fonte
1
você prefere o shell globbing OVER usando find quando o diretório contém muitos arquivos? erro de digitação??
Akira
1
Suponho que o OP não queira uma lista de subdiretórios e desconheça a opção de passar -maxdepth 1para find.
intuited

Respostas:

19

Embora xargs -0se destine a ser usado para entrada delimitada por \ 0 (como find -print0), lsnão existe essa opção para delimitar sua saída dessa maneira.

Contudo,

ls -1 /path/glob | tr '\n' '\0' | xargs -0 -n 1 basename

faria o truque para converter novas linhas em nulos ao longo do caminho. Isso permite que o xargs trabalhe com nomes que possuem espaços.

EDIT: adicionado -n 1ao xargs

Steve Folly
fonte
Isso não funciona para mim: basename: extra operand \ 033 [0m / net / nas / data / languages ​​/ pypm / sites / rex / free / 2.6 / macosx / pool / v / vi / virtualenv-1.4.4_macosx_2.6_1.pypm \ 033 [ 0m'`
Srid diz Restabelecer Monica
@ Sridhar: você pode precisar do -n 1que sugeriu em outro lugar como uma opção xargs? (Resposta editada)
Steve Folly
Embora eu pessoalmente prefira minha própria resposta (como quase nunca preciso lidar com espaços nos nomes de arquivos), vou marcar isso como a resposta, pois ela também lida com espaços.
Srid diz Restabelecer Monica
Se a versão para mac do xargs suportar a -dopção (delimitador), você poderá fazê-lo ls ... | xargs -d '\n' -n 1 basename.
intuited
12

Eu uso isso:

ls | tr '\n' '\n'

Ele fornece uma lista como:

file1.mp3
file2.mp3
file3.mp3
...
arrayown
fonte
3
É essencialmente o mesmo que ls -1(e cor desabilitada), como lsimplica aqueles que não estão gravando em um terminal. Parece que você está perdendo um pouco o assunto, pois o problema está eliminando o nome do diretório ao especificar lsargumentos de caminho usando caracteres curinga. Tente ls -d "$PWD/"* | tr '\n' '\n'ver qual é o problema real.
Daniel Beck
-1 - não sei por que as pessoas continuam votando nessa resposta. Ele não apenas faz o mesmo ls -1, mas também não funciona quando os globos são usados, como Daniel Beck apontou.
slhck
-1 - É o mesmo que ls -1, e só funciona no diretório atual, não com um caminho como ls path/*.
Brendan Byrd
5
ls -1 <path> | sed 's#.*/##'
mpez0
fonte
Ah! Finalmente, algo que funciona com vários argumentos!
Aurélien Ooms
4

awk solução:

ls -1 /path/glob | awk -F'/' '{print $NF}'
Amnon
fonte
2

ls [caminho opcional] | xargs -0 basename

Glen Y.
fonte
2
-1: Não é possível delimitar nomes por \ 0, o que xargs -0está procurando.
Steve Folly
2

O nome de base do GNU e o nome de base do FreeBSD aceitam um -aargumento que permite a você passar vários caminhos para o comando. Isso funciona muito bem com globbing shell.

basename -a /path/glob*
dcoles
fonte
1

Você disse que prefere dar uma olhada find, mas sabia que os dois não são mutuamente exclusivos? Globbing acontece em qualquer comando que você executa, não apenas ls. Por exemplo:

$ export BASE=/net/nas/data/languages/pypm/sites/rex/free/2.6

$ echo $BASE/*/pool/v/vi/virtual*1.4.4*pypm | xargs basename
$ ls $BASE/*/pool/v/vi/virtual*1.4.4*pypm | xargs basename
$ find $BASE/*/pool/v/vi/virtual*1.4.4*pypm -print0 | xargs -0 basename

Observe que o exemplo find pode usar -print0, o que é útil se seus caminhos contiverem espaços em branco (as trsoluções baseadas mencionadas em outros lugares funcionam muito bem em espaços normais, mas não em arquivos que contêm novas linhas reais).

Por fim, se você tiver acesso ao GNU find, também poderá usar -printf, o que evita a chamada de nome de base completamente:

$ find $BASE/*/pool/v/vi/virtual*1.4.4*pypm -printf '%f\n'
Ryan Bright
fonte
Infelizmente, a -printfopção não está disponível na versão MacOSX de find.
Srid diz Restabelecer Monica
Boa decisão; desculpas pela supervisão. Eu atualizei a resposta.
Ryan Brilhante
-3

vá para o diretório em que você tem todos os seus arquivos e digite.

find *.pypm
justiça
fonte
1
OP declarou explicitamente que ele não quer usar find.
precisa saber é o seguinte
1
Além disso, isso nem faz o que o OP precisa. (Nota: Você deve usar find . -name '*pypm'se em tudo ... apenas colocar o glob seguinte para encontrar a nada - então você poderia apenas escrever ls *.pypm.)
slhck