ls: Não mostra diretórios que correspondem ao mesmo padrão em pesquisas com curinga, somente arquivos

4

Suponha que eu tenha algo como o seguinte, uma típica situação de PC comercial:

drwxr-xr-x 1 whatever whoever       3 Oct  3 16:40 invoices2009
drwxr-xr-x 1 whatever whoever       4 Oct  3 16:40 invoices2010
drwxr-xr-x 1 whatever whoever       2 Oct  3 16:40 invoices2011
-rwxr-xr-x 1 whatever whoever  440575 Oct  3 16:40 tax2010_1
-rwxr-xr-x 1 whatever whoever  461762 Oct  3 16:40 tax2010_2
-rwxr-xr-x 1 whatever whoever  609123 Oct  3 16:40 tax2010_3

Agora vamos ser preguiçosos e digitar:

$ ls -l *2010*

Supondo que seja algo no diretório invoices2010, ele não funcionará como esperado. Como o nome do diretório também contém o ano 2010 , ls também listará os arquivos em invoices2010 , embora eu queira listar apenas esses no diretório atual. Ainda mais engraçado: imagine que os arquivos tax2010 * não estavam lá e não havia aqueles três diretórios como no exemplo, mas 50 deles. Sim, tentei: ls nem sequer indica quais arquivos estão em qual diretório, mas simplesmente listá-los de cima para baixo, como se todos os arquivos residissem no diretório atual (a menos que você especificar explicitamente a opção -R , certamente sei que)

Além disso, sei que também posso fazer isso com find , mas há também alguma maneira de realizar essa tarefa com uma simples ls one-liner (que, obviamente, tem uma sintaxe bem menos complicada) ?

    
por syntaxerror 05.10.2012 / 09:38

6 respostas

12

Parece que sua pergunta é "Como listar arquivos por padrão excluindo diretórios com ls apenas".

Não há como fazer isso com ls puro. Você pode combinar ls + grep como:

ls -ld *2010* | grep -v '^d'

No entanto, é muito melhor usar find para isso:

find . -maxdepth 1 -type f -name "*2010*"
    
por 05.10.2012 / 10:16
2

Não é possível filtrar seletivamente os diretórios usando apenas ls . Você precisa do find ou ls | grep , conforme descrito na resposta do rush . Mas, para o seu exemplo específico, para responder à pergunta que você fez em seu comentário :

So again: I want the tax* files in the current directory to be listed, but the directory "invoices2010" which resides in the same working directory and which also matches the given 2010 wildcard pattern should be skipped in the listing.

você pode fazer

ls -l --ignore='invoices*' *tax2010*

que filtra qualquer coisa que corresponda ao padrão% shell do ignore .

    
por 05.10.2012 / 10:26
1

Use zsh…

ls -l *2012*(.)

O qualificador de glob . significa apenas arquivos regulares.

    
por 06.10.2012 / 23:30
0

ls -dlp *2010* seria um bom começo para a solução, mas depende da aparência da saída.

    
por 05.10.2012 / 09:43
0

Não use grep com ls,

No bash, você pode mostrar arquivos com um "2010" em seu nome, mas sem olhar com um número:

ls -l *[!0-9]2010*

    
por 07.10.2012 / 08:04
0

Existem razões para não grep contra ls , mas se você as desconsiderar, isso funciona. Use o comando ls como uma matriz de entrada, chame ls -ld em cada entrada canalizada para grep para excluir diretórios com a saída enviada para nulo e, se tiver êxito, repita a entrada original:

for list in 'ls' ; do ls -ld $list | grep -v ^d > /dev/null && echo $list ; done ;

Você pode inverter o grep e a saída condicional, os mesmos resultados:

for list in 'ls' ; do ls -ld $list | grep ^d > /dev/null || echo $list ; done ;

EDIT: Meu mau, isso funciona sem uma correspondência de padrão, mas se você adicionar uma pesquisa curinga como no OP acima, e você tem um diretório que corresponde ao padrão, a saída ainda inclui sistema mensagens para que você precise filtrar mais para obter apenas a lista de arquivos.

EDITAR novamente: barras invertidas fixas em / dev / null.

    
por 07.10.2013 / 11:14