Lógica de correspondência de padrões de shell

0

Qual é a diferença lógica entre

  1. ll -d !(.*@(ry|rc))
  2. ll -d !(.*{ry,rc})

?

Usando-os no meu diretório home, o segundo corresponde a .bash_history e .xinputrc , enquanto o primeiro não.

Nota:

$ shopt extglob
extglob         on
    
por sancho.s 13.10.2017 / 10:46

1 resposta

4
ll -d -- !(.*{ry,rc})

combina expansão globbing e cinta. Primeiro é expandido para:

ll -d -- !(.*ry) !(.*rc)

E as globs se expandiram individualmente. E o primeiro corresponde a .inputrc (em bash -O extglob mas não em ksh de onde essa sintaxe vem nem zsh em ksh emulação, pois são arquivos ocultos e arquivos de ponto não são explicitamente solicitados).

Você pode verificar isso em um diretório em que esses globs não correspondam a nenhum arquivo (caso em que os globs são deixados intactos, outro bash pode apresentar uma funcionalidade que você pode contornar com shopt -s failglob ) em um diretório onde você não tem permissão de leitura:

$ chmod a-r .
$ bash -O extglob -c 'echo ll -d -- !(.*{ry,rc})'
ll -d -- !(.*ry) !(.*rc)

Enquanto em

ll -d -- !(.*@(ry|rc))

Isso é um glob.

Aqui, você também pode fazer:

ll -d -- !(.*r[cy])

Ou:

ll -d -- !(.*rc|.*ry)

Observe que bash também inclui . e .. nessa expansão. Se você quisesse excluí-los (como eu tenho certeza que você faria), mas ainda incluir arquivos ocultos, você precisaria:

shopt -s dotglob
ll -d -- !([.]*@(rc|ry))

Ou você pode excluí-los explicitamente:

ll -d -- !(.*@(rc|ry)|.|..)

Em zsh -o extendedglob , gostaria de fazer:

ll -d -- ^.*(rc|ry)(D)

(onde (D) ativa dotglob somente para esse glob).

    
por 13.10.2017 / 11:19