Listar arquivos que correspondem a um padrão, mas ignoram arquivos que correspondem a outro padrão?

12

Digamos que eu tenha um diretório com os arquivos a1, a2, a3, b1, b2, b3. Eu só quero combinar arquivos que começam com, amas não contêm 3. Eu tentei, ls -I "*3" *a*mas ele retorna a1 a2 a3, mesmo que não queira que ele corresponda a3. Isso é possível com ls?

Steven
fonte
interessante conjunto diverso de respostas aqui, mas uma explicação de por que ls -I '* 3' a * falha seria edificante. e / ou por que a lista globbed do shell não está sendo posteriormente filtrada pela opção ignorar para ls?
Theophrastus
A página de manual diz sobre a opção -I: do not list implied entries matching shell PATTERNno entanto, não explica o que significa implícita , mas acho que se aplica apenas a arquivos que lsrecebem expansões glob - e lsnão expande a a*, o shell faz isso .
Murray Jensen

Respostas:

14

Somente:

shopt -s extglob  
ls a!(*3*)
  • shopt -s extglob ativa globbing prolongado.
  • a coincide com o início a
  • !()nega a partida dentro do ()...
    • *3*que é 3e qualquer coisa antes ou depois dela.

$ touch 1 2 3 a1 a2 a3 b1 b2 b3 aa1 aa2 aa3 a2a a3a
$ ls a!(*3*)
a1  a2  a2a  aa1  aa2
caos
fonte
1
Para sua informação, é necessário #set -s extglob
Brian
@Brian Yea, acabei de notar ^^ #
caos
8

As respostas existentes indicam bem a melhor maneira de fazer isso com os globs; Incluírei isso porque, na maioria dos casos, findé uma opção melhor se você deseja criar scripts ou processar mais:

$ find . -maxdepth 1 -name 'a*' -not -name '*3*'
./a1
./a2

Você pode fornecer a resposta xargspara ações fáceis ou um while readloop para coisas mais complicadas.

Tom Hunt
fonte
4

Uma maneira fácil é

  • para listar todos os arquivos que correspondem a*
  • exclua todas as linhas que contêm um 3

O comando UNIX é

ls -1 a* | grep -v 3

ls -1 mostra um arquivo por linha.

grepnormalmente encontra linhas que correspondem a um padrão, mas com -vesse comportamento é invertido, ou seja, grep encontra linhas que não correspondem a esse padrão.

Peter K
fonte
2
Olá Peter! Seria melhor explicar, com o máximo de detalhes relevantes, como sua solução funciona.
dhag
2
Análise lsnão é uma idéia Goob: mywiki.wooledge.org/ParsingLs
caos
3

Com zsh, usando o ~ operador glob :

setopt extendedglob
print -rl -- a*~*3*

Com gnu lsvocê pode usar duas --ignoreopções:

ls -I '[^a]*' -I '*3*'

o primeiro ignora todos os nomes de arquivos que não começam ae o segundo ignora os nomes de arquivos que contêm3

don_crissti
fonte