Problemas ao usar múltiplos * no comando grep

0

Alguém sabe por que usar dois * em um comando grep não retornará nada. Meu comando original é o seguinte:

find | grep 0000\:00\:*.0/usb1/authorized_default

Neste exemplo, estou tentando retornar um arquivo que não conheço o nome da pasta PCI. Este comando funciona perfeitamente e como esperado (tomando o * como um caractere curinga) e descobrindo que o usb1 está na pasta '1a'.

Por que o grep não retorna nenhum resultado se eu colocar outro curinga no comando para substituir 'usb1' por 'usb *'? Meu objetivo final é retornar todos os arquivos do authorized_default que eu percebo que podem ser feitos de outras maneiras e provavelmente de maneira mais eficiente. Minha pergunta então não é como eu posso fazer isso, mas por que o grep não retorna um resultado quando eu coloco outro símbolo '*' na equação?

find | grep 0000\:00\:*.0/usb*/authorized_default

Agradecemos antecipadamente pelo seu tempo e respostas.

    
por James Lane 23.05.2018 / 05:12

2 respostas

6

grep usa expressões regulares , não shell globs .

A regex 0000:00:*.0/usb1/authorized_default corresponde à string 0000:00 + zero ou mais dois-pontos + qualquer caractere + 0/usb1/authorized_default .

Se você trocar o * e o . , ele corresponderá a qualquer string que contenha 0000:00 seguido por 0/usb1/authorized_default . ( .* corresponde a qualquer número ( * ) de qualquer caractere ( . ).)

Da mesma forma, usb*/ corresponderá a us/ , usb/ , usbbb/ etc, mas não usb1 .

Na verdade, há também o problema de que o * não-referenciado no argumento para grep é considerado como um caractere de glob pelo shell , antes que grep o veja. Portanto, se houver arquivos que correspondam a 0000\:00\:*.0/usb*/authorized_default como um padrão glob, isso afetará a sequência que vai para grep . Múltiplas correspondências iriam como vários argumentos e grep usaria os primeiros após o primeiro como nomes de arquivo.

Coloque aspas em torno de quaisquer expressões regulares na linha de comando para evitar isso.

Em qualquer caso, você nem precisa do grep aqui, como diz @Kusalananda. A opção -name para find pode ser usada para corresponder nomes de arquivos a um padrão glob. Pelo menos algumas implementações de find também têm a opção -regex para corresponder nomes de arquivos a expressões regulares.

Há também várias variantes de expressões regulares, consulte: Por que minha expressão regular funciona em X, mas não em Y

    
por 23.05.2018 / 05:21
2

Como ilkkachu já apontou, grep usa expressões regulares básicas, o que significa que :* corresponde a zero ou mais : e b* corresponde a zero ou mais b .

Não use grep da saída de find , em vez disso, use find para procurar seu arquivo. No caso geral, nomes de arquivos podem conter novas linhas, o que faria com que o grepping não funcionasse. Usar find para filtrar diretamente os nomes de caminho que você deseja ver também é mais eficiente e seguro.

find . -type f -name 'authorized_default'

Se você tiver que fazer correspondência em outras partes do nome do caminho:

find . -type f -path '*0000:00:*.0/usb*/authorized_default'

-path funciona como -name , mas corresponde a um padrão globbing de nome de arquivo no caminho inteiro, em vez de apenas na parte do nome do caminho do arquivo (um * pode corresponder a um ou vários / ).

Relacionados:

por 23.05.2018 / 08:00

Tags