shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script-pt] Comportamento inconsistente nas extglobs?


From: Julio C. Neves
Subject: Re: [shell-script-pt] Comportamento inconsistente nas extglobs?
Date: Thu, 5 Mar 2020 11:10:58 -0300

Fala Blau,
Vc gosta tanto de bisbilhotar por baixo do capô que ninguém se sentiu seguro para responder seus questionamentos. Eu continuo achando que a resposta que te dei pela lista Shell do Telegram (quem quiser se inscrever nessa lista é só responder a esse e-mail).

Ainda não consegui tempo para ler o seu artigo em https://gitlab.com/blau_araujo/artigos/-/blob/master/bash/extglob/extglob.md, mas pela rápida folheada que dei, me deixou muito interessado.

Duas coisas:
1 - A seguir vai o que já escrevi no meu livro sobre o tema, que pode ser que vc aproveite alguma coisa:

O builtin shopt

O shopt é um comando pouco usado, porém ele conta com diversas facilidades propiciadas pelas suas opções, das quais veremos só as mais importantes, Para você ter uma ideia, o comando shopt quando usado sem argumentos lista o estado de cada uma dessas opções. Então vamos usá-lo para contar quantas existem:

$ shopt | wc -l

46

O shopt possui 4 opções, mas só costumamos usar duas:

-s - Liga uma facilidade;

-u - Desliga uma facilidade.

Ganhando o jogo com mais curingas - extglob

O Shell possui, além do globbing normal - que são os curingas conhecidos por todos para expansão de nomes de arquivos e diretórios (*, ?, [a-z] e [!a-z]) - um globbing estendido. Este globbing estendido, em alguns casos, poderá ser muito útil e sempre será mais veloz que o código que ele substituirá, como o pipe junto com o grep. (normalmente se faria ls <ESCOPO> | grep ... ou echo <ESCOPO> | grep ...)

Nas linhas a seguir, LISTA contém um ou mais padrões separados por uma barra vertical (|), que, diga-se de passagem, é tratada como um OU lógico em Expressões Regulares e em diversos comandos que em sua sintaxe aceitam a formação de padrões de pesquisa usando os caracteres coringa (como o comando case, por exemplo). Veja:

?(LISTA)

*(LISTA)

+(LISTA)

@(LISTA)

!(LISTA)

Para poder utilizá-los precisa executar o comando shopt -s conforme o exemplo a seguir:

$ shopt -s extglob Liga a facilidade (argumento) extglob

$ ls arq*

arq arqdados arqdadosdados arqutils

$ ls arq?(dados)

arq arqdados

$ ls arq*(dados)

arq arqdados arqdadosdados

$ ls arq+(dados)

arqdados arqdadosdados

$ ls arq@(dados)

arqdados

$ ls arq!(dados) Divertido esse

arq arqdadosdados arqutils

$ ls arq+(dados|utils)

arqdados arqdadosdados arqutils

$ ls arq@(dados|utils) O mesmo que ls arq {dados,utils}

arqdados arqutils

Obrigado, Tiago Peczenyj!

O Tiago me deu as dicas anteriores, mas existem outras... teste as <OPCOES> a seguir dentro do comando shopt -s <OPCOES>.

=====================================================

2 - A um tempão estou para testar esse extglob junto da expansão de parâmetros. Como vc sabe as expansões aceitam curingas para expansão de arquivos. Como isso se comportaria com extglob? O teu artigo está implementando isso ou é um algo mais a pesquisar/escrever?

Abraços,
Julio

» Não tem tempo para fazer um curso presencial?
» Na sua cidade não tem nenhum bom curso de Linux?
» Em 27/01/2020 abriremos uma semana de inscrições
» para uma nova turma. Veja mais detalhes em:

Também damos treinamento em sua empresa
em qualquer cidadecom certificado e nota fiscal.







Em ter., 3 de mar. de 2020 às 17:54, Blau Araujo <address@hidden> escreveu:

Salve, pessoal!


Uma perguntinha de quem gosta de olhar debaixo do capô do Bash:

Supondo que numa pasta eu tenho os arquivos:

a.txt  aa.txt  .txt

Considerando também que `extglob` está habilitado e `dotglob` está desabilitado, eu tenho as seguintes saídas:

---

# 1 - Casa apenas com zero ou um caractere 'a'...
:~$ ls ?(a).txt
a.txt  .txt

# 2 - Casa com zero ou mais caracteres 'a'...
:~$ ls *(a).txt
aa.txt  a.txt .txt

# 3 - Casa com tudo que não for apenas um 'a'...
:~$ ls !(a).txt
aa.txt

---

A questão é: por que o aquivo '.txt' foi expandido (para nossa surpresa) nos comandos 1 e 2 mas não foi expandido (como esperado) no comando 3?

A minha pergunta não tem nem tanto a ver com a implementação ou o funcionamento da sintaxe `!(lista-de-padrões)`, mas com a confirmação ou não de uma possível inconsistência do Bash. Quer dizer, as regras que valem para o '*' não valem para algumas sintaxes estendidas, menos uma delas?

Quer dizer, nós temos aparentemente duas regras para expansões que fazem basicamente a mesma coisa:

* Com `*` e `!(lista-de-padrões)`, o Bash não expande nomes de arquivos iniciados com ponto (`.`), a menos que a opção `dotglob` esteja habilitada.

* Com `?(lista-de-padrões)` e `*(lista-de-padrões)`, ele já expande nomes de arquivos iniciados com ponto (`.`), mesmo com `dotglob` desabilitado.

A minha suspeita é que, no caso do casamento negado, o Bash primeiro expande os nomes de arquivos como faria com um asterisco, caso em que arquivos com nomes iniciados com ponto não são expandidos, para só depois excluir os nomes que casem com o padrão.

Então, será que é isso?


Abraços!

-- 
Blau Araujo
_______________________________________________
Lista brasileira de usuários de shell script
Endereço de e-mail da lista: address@hidden
Para se inscrever ou desinscrever acesse: https://lists.nongnu.org/mailman/listinfo/shell-script-pt
Para ver os arquivos da lista (mensagens anteriores) e pesquisar nelas, acesse https://lists.nongnu.org/archive/html/shell-script-pt/

NOTA: A lista anterior, no Yahoo Groups, foi *desativada*. Por favor utilize somente esta.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]