Como grep para guias sem usar guias literais e por que não funciona?

146

Quando procuro guias em um arquivo com (e) grep, uso a guia literária ( ^v + <tab>). Não posso utilizar \tcomo um substituto para guias em expressões regulares. Com eg sed esta expressão funciona muito bem.

Portanto, existe a possibilidade de usar um substituto não literário <tab>e quais são os antecedentes de um não-trabalho / não interpretado \t?

Lasall
fonte

Respostas:

206

grep está usando expressões regulares, conforme definido pelo POSIX . Por qualquer motivo, o POSIX não definiu \tcomo tab.

Você tem várias alternativas:

  • diga ao grep para usar as expressões regulares conforme definido pelo perl (o perl tem \tcomo tab):

    grep -P "\t" foo.txt

    a página de manual avisa que esse é um recurso "experimental". pelo menos \tparece funcionar bem. mas recursos perl regex mais avançados podem não.

  • use printf para imprimir um caractere de tabulação para você:

    grep "$(printf '\t')" foo.txt
  • use o caractere de tabulação literal:

    grep "^V<tab>" foo.txt

    ou seja: digite grep ", pressione ctrl+v, depois pressione tabe digite " foo.txt. pressionar ctrl+vno terminal faz com que a próxima tecla seja tomada literalmente. isso significa que o terminal inserirá um caractere de tabulação em vez de acionar alguma função vinculada à tecla tab.

  • use o recurso de cotação ansi c do bash:

    grep $'\t' foo.txt

    isso não funciona em todas as conchas.

  • use awk:

    awk '/\t/'
  • use sed:

    sed -n '/\t/p'

Consulte o artigo da wikipedia sobre expressões regulares para obter uma visão geral das classes de caracteres definidas no POSIX e em outros sistemas.

lesmana
fonte
baseando-se a resposta de enzotib me deixe acrescentar o seguinte: grep $'\t' foo.txt(mas eu normalmente escrever fgrepem vez de grep)
Walter Tross
Eu precisava disso, combinado com o uso do valor de uma variável de ambiente. Eu usei grep "$(printf '\t')${myvar}" foo.txt. Funcionou bem. Com algumas tentativas, não consegui que o último formulário funcionasse.
sancho.s
11
Existe alguma razão para que a planície grepnão possa silenciosamente interpretar \tcomo guia? O POSIX exige que isso \tsignifique algo mais? Talvez deva corresponder apenas a um literal \ seguido de um t?
Aaron McDaid
Talvez seja interessante notar que o BSD (incluindo OSX) grep não possui a opção -P.
TextGeek #
Da página de manual This is highly experimental and grep -P may warn of unimplemented features.Provavelmente não é uma boa ideia usar -Pem sistemas legados. A printfescolha é melhor
Avindra Goolcharan 10/04
13

Não é exatamente a resposta que você gostaria de ouvir, mas um possível uso de seqüências de escape é fornecido pelo bash

command | grep $'\t'

(não coloque entre aspas duplas!).

enzotib
fonte
11
não há necessidade de -E (o que é pesquisado não é regex). Também não há necessidade de canalizar a partir de um comando. Dito isto, obrigado por apontar esse recurso bastante negligenciado do bash (cordas individuais citado precedido por $)
Walter Tross
2
Na verdade, sugiro que o @enzotib edite a resposta de maneira simples grep $'\t'.
Teemu Leisti
Deve-se enfatizar que esse é um recurso do bash e (silenciosamente!) Fará a coisa errada se executado por algum outro shell (como o dash, que é o padrão para scripts de shell no Ubuntu e outros)
xjcl
2

awk '/\t/' é minha solução alternativa favorita:

printf 'a\t\nb' | awk '/\t/'

Saída: a\t.

Ciro Santilli adicionou uma nova foto
fonte
1

Pode-se sempre recorrer ao uso de código hexadecimal ascii para tab:

$ echo "one"$'\t'"two" > input.txt                                 

$ grep -P "\x9" input.txt                                          
one two

$ grep $'\x9' input.txt                                            
one two
Sergiy Kolodyazhnyy
fonte