Como encontrar linhas que começam com **

8

Preciso descobrir se alguma linha de um arquivo começa com **.

Não consigo descobrir como fazê-lo porque *é interpretado como um curinga pelo shell.

grep -i "^2" test.out

funciona se a linha começa com um 2, mas

grep -i "^**" test.out 

obviamente não funciona.

(Também preciso saber se essa linha termina com um, )mas ainda não o fiz).

Shar Hunter
fonte

Respostas:

18

Use o \caractere para escapar do * para torná-lo um caractere normal.

grep '^\*\*' test.out

Observe também as aspas simples 'e não as aspas duplas "para impedir que o shell expanda as coisas

Stephen Harris
fonte
3
O primeiro *não precisa escapar nesse caso específico, fwiw.
23416 don_crissti
5
Embora não precise ser escapado, não sair do primeiro asterisco será mais confuso para um observador casual, como se você estivesse correspondendo "a qualquer número de partidas de linhas seguidas por um asterisco". Qualquer coisa que torne uma regexp mais intuitiva para um mantenedor é uma boa ideia. =)
Compilador conspícuo
1
O uso de aspas duplas também impediria a expansão, não apenas aspas simples. Conselho errado aqui.
Rems4e
@ rems4e usando aspas duplas impediria o shell de expandir os asteriscos, mas não de interpretar as barras invertidas. Com aspas duplas, você teria que usar grep "^\\*\\*"para que o grep receba a ^\*\*sequência necessária para evitar a interpretação dos asteriscos como quantificadores de regex.
Aaron
7

Como você deseja verificar a linha que começa **e termina com ), você pode combinar duas grepoperações como esta,

grep '^*\*' test.out | grep ')$'

Ou com um único grepcomando como este,

grep -E '^\*\*.*\)$' test.out

Explicação

  • ^\*\* : linha de partida que começa com **
  • .* : combinar tudo depois **
  • \)$: linha de partida que também tem )no final da linha.
Rahul
fonte
3

Não é a concha

Nenhuma das respostas até agora abordou o problema real. Seria útil explicar por que não funciona como o esperado.

grep -i "^**" test.out

Porque você citou o padrão para grep , não* é expandido pelo shell. É passado para grep como está. Isso é explicado na página de manual [1] do bash [2] :

A inclusão de caracteres entre aspas duplas preserva o valor literal de todos os caracteres entre aspas, com exceção de $, `, \ e, quando a expansão do histórico está ativada,!

É expressões regulares regulares regulares

Uma expressão regular é um padrão que descreve um conjunto de cadeias.

*é um dos principais padrões nas expressões regulares. Por padrão, o grep interpreta da seguinte maneira:

* The preceding item will be matched zero or more times.

Isso significa que seu padrão, tal como está, ^**não faz muito sentido. Possivelmente, ele tenta coincidir com o início da linha zero ou mais vezes , duas vezes. O que quer que isso signifique.

A solução é citá- lo:

Qualquer meta-caractere com significado especial pode ser citado precedendo-o com uma barra invertida.

grep -i "^\*\*" test.out


[1] Eu não recomendo a leitura. Por favor, use man dashou similar.

[2] Nenhum shell foi dado, então eu assumo o bash .

tubo
fonte
2

Outras opções.

Você pode usar sedou awktambém

$ sed -n '/^*\*/p' test.out
$ awk '/^*\*/' test.out

Conhecer linhas que terminam com o )uso também grepou sedouawk

$ grep ')$' test.out
$ sed -n '/)$/p' test.out
$ awk '/)$/' test.out
tachomi
fonte
Obrigado a todos! Eu realmente aprecio a ajuda neste!
Shar Hunter
1
E a linha combinada awk: '/^*\*/&&/)$/'...
jasonwryan
0

Esta é a versão completamente sem aspas: grep ^\\*\\* test.out. Para passar uma barra invertida literal do shell para o grep, ele precisa ser escapado.

Isso funciona desde que você não tenha arquivos no diretório que iniciem ^\e contenham outra barra invertida.

Beat Bolli
fonte