Grep exclui caracteres curinga que não estão funcionando

1

Estou usando o Ubuntu 14.04 LTS.

Estou brincando com o grep e acertei um problema passando grep para ls. Todos os exemplos estão limitados a um diretório atual, não recursivo.

Se eu quiser listar todos os arquivos que contêm um dígito em seu nome:

ls | grep [0-9]

Se eu quiser listar todos os arquivos que contêm "d", "h", "m" como uma primeira letra:

ls | grep ^[dhm]

Se eu quiser listar todos os arquivos que contêm um dígito como primeira letra:

ls | grep ^[0-9]

No entanto, quando tento usar ! dentro de [] , o ! não está incluído:

user@host:~$ ls | grep [0-9]
1.log
2.log
3.log
hs_err_pid4015.log
Untitled 1.odt
v1.odt

user@host:~$ ls | grep [!0-9]
1.log
2.log
3.log
hs_err_pid4015.log
Untitled 1.odt
v1.odt

O mesmo implica se eu tentar usá-lo com ^

user@host:~$ ls | grep ^[0-9]
1.log
2.log
3.log

user@host:~$ ls | grep ^[!0-9]
1.log
2.log
3.log

Eu passei vários dias lendo outros posts, páginas de manual, artigos etc sobre grep e curingas, mas não consigo entender. Eu tentei colocá-los em ' e " , combinando os dois sinalizadores de caracteres curinga ( ^ e ! ) em [[]] etc.

Nada mostra uma saída diferente dos exemplos acima.

Por favor, não me mostre a solução. Explique meus erros e deixe-me descobrir por mim mesmo.

    
por Iliyan Stankov 05.01.2017 / 05:53

1 resposta

4

O token Regex dentro da classe de caractere para negação é ^ , não ! .

Então você precisa:

ls | grep '^[^0-9]'

Se você usar ls | grep ^[!0-9] , então, em [] , ! será tratado literalmente e 0-9 será expandido da maneira usual.

Também para esse tipo de tarefa trivial, use shell globbing, o Regex é um pouco demais para isso, e também não analisa ls ; você poderia simplesmente fazer:

ls [^[:digit:]]*
ls [![:digit:]]*

Observe que bash suporta ^ e ! como token de negação de padrão dentro da classe de caracteres durante a globulação.

Se você não quer depender de você, locale :

ls [^[0-9]]*
ls [![0-9]]*
    
por heemayl 05.01.2017 / 05:57