grep uma guia no UNIX


418

Como grepseparo (\ t) os arquivos na plataforma Unix?


53
é só usar grep "<Ctrl+V><TAB>", funciona: (se primeira vez tipo grep ", em seguida, pressione a tecla Ctrl + V combinação, em seguida, pressione a tecla TAB, em seguida, digite "e tecle enter, voilà!)
torre

16
ctrl + v é uma IDEIA MUITO MAU! ... sim, pode funcionar a partir do comando do console, mas NÃO FUNCIONARÁ AO TIPO EM UM SCRIPT (você está à mercê do editor, por exemplo, eu uso mcedit e ctrl + v NÃO trabalho lá)
THESorcerer

Relacionados, mas não uma duplicata: Pesquisar por abas, sem -P, usando 'grep'
Peter Mortensen

Veja também: askubuntu.com/questions/53071/... (link abaixo também)
shiri

Respostas:


375

Se estiver usando o GNU grep, você pode usar o regexp no estilo Perl:

grep -P '\t' *

Não parece funcionar contra o meu padrão. Tentar usar essa sintaxe não imprime nada. (É o Mac OS X variante diferente?)
futureelite7

2
@futureelite: de acordo com os documentos da Apple ( developer.apple.com/Mac/library/documentation/Darwin/Reference/… ), o programa grep do Mac OS X deve oferecer suporte à opção -P. Considere criar uma nova pergunta, em superuser.com.
descontraia

3
Isso é muito bom para o GNU UNIX, mas e o POSIX Solaris, AIX e HP-UX? Aqueles não sabem nada sobre -Popção.
rook

21
@rook GNU não é UNIX.
Lily Chung

5
no Mac OSX você pode dar um padrão usando -e
Faisal Feroz

314

O truque é usar o sinal $ antes de aspas simples . Também funciona para corte e outras ferramentas.

grep $'\t' sample.txt

7
A dica do salva-vidas salva vidas! Funciona zshtambém, até onde eu sei. Você poderia comentar qual é a semântica desse $sinal?
Romain

2
Não funciona se a String contiver algo diferente de '\ t'. Como você pesquisaria "\ t" (tabulação + espaço), por exemplo?
Raman

6
Raman: Você pode usar $'\t'' '. Um exemplo real que mostra que ele também funciona com sh (não apenas o bash, que não é instalado por padrão no Android) é busybox grep -oE '^nodev'$'\t''fuse$' /proc/filesystems.
v6ak

5
Eu acho que $ '...' é um idioma bash. Provavelmente não funciona em sh. Não sei sobre csh ou tcsh.
Edward Falk

5
De 'man bash': as palavras da forma $ 'string' são tratadas especialmente. A palavra se expande para cadeia, com caracteres de escape de barra invertida substituídos conforme especificado pelo padrão ANSI C. Seqüências de escape barra invertida, se presentes, são decodificados ...
broeni

84

Eu nunca consegui fazer o metacaractere '\ t' funcionar com grep. No entanto, encontrei duas soluções alternativas:

  1. Usando <Ctrl-V> <TAB>(pressionando Ctrl-V e digitando a guia)
  2. Usando o awk: foo | awk '/\t/'

4
A | awk '/\t/'solução funcionará para todos os shells, plataformas e sistemas.
Samveen

6
+1 para a solução POSIX portátil e não usar bashisms, zshism, GNUism e linuxisms.
Jens

1
ctrl-V não é útil se você deseja copiar e colar (de suas anotações ou de um script). Melhor usar uma solução explícita que tem um visível '\ t', OAT literais (ou seja, aqueles que se parecem com espaços em branco) são muitas vezes convertidos em SPC quando copypasting ...
plijnzaad

awkfunciona bem aqui, mas em alguns testes na minha máquina com arquivos muito grandes é cerca de 30% mais lento que o uso grep -P. Isso pode ser trivial e irrelevante com base no caso de uso e awkpode ser melhor simplesmente por legibilidade e portabilidade.
theferrit32

43

A partir desta resposta no Ask Ubuntu:

Diga ao grep para usar as expressões regulares definidas pelo Perl (o Perl tem \tcomo tab):

grep -P "\t" <file name>

Use o caractere de tabulação literal:

grep "^V<tab>" <filename>

Use printfpara imprimir um caractere de tabulação para você:

grep "$(printf '\t')" <filename>


ctrl-V não é útil se você deseja copiar e colar (de suas anotações ou de um script). Melhor usar uma solução explícita que tem um visível '\ t', OAT literais (ou seja, aqueles que se parecem com espaços em branco) são muitas vezes convertidos em SPC quando copypasting
plijnzaad

31

Uma maneira é (isso é com o Bash)

grep -P '\t'

-P ativa expressões regulares do Perl para que funcione.

Como o usuário desenrola , pode ser específico ao GNU grep. A alternativa é literalmente inserir uma guia lá se o shell, editor ou terminal permitir.


Opção P desconhecido no shell ksh
Sachin Chourasiya

Como o desenrolar diz, pode ser específico ao GNU grep. Apenas esclarecido.
Tjmoore 01/12/2009

Como você adiciona uma guia? Ele não inicia o processo de conclusão automática quando você pressiona o botão tab? (que o trabalho poder em um script bash, mas não na linha de comando)
AntonioCS

1
@AntonioCS conforme observado acima por SamKrieg, para que o Shell permita digitar qualquer caractere, basta digitar CTRL-v primeiro. Veja também askubuntu.com/questions/53071/…
Denis Arnaud

2
-P é específico para grep, não para qualquer shell. -P deve funcionar em qualquer shell, desde grep GNU está instalado
plijnzaad

13

Outra maneira de inserir a guia literalmente dentro da expressão é usar a $'\t'citação menos conhecida no Bash:

grep $'foo\tbar'        # matches eg. 'foo<tab>bar'

(Observe que se você estiver correspondendo para cadeias fixas, poderá usá-lo no modo '-F'.)

Às vezes, o uso de variáveis ​​pode tornar a notação um pouco mais legível e gerenciável:

tab=$'\t'               # `tab=$(printf '\t')` in POSIX
id='[[:digit:]]\+'
name='[[:alpha:]_][[:alnum:]_-]*'
grep "$name$tab$id"     # matches eg. `bob2<tab>323`

10

Não é exatamente isso que você está procurando, mas pode funcionar no seu caso

grep '[[:blank:]]'

Equivalente a

grep -P '[ \t]'

Por isso, encontrará Espaço e Tab.

§ Classes de caracteres

Observe que ele não é anunciado no meu man grep, mas ainda funciona

$ man grep | grep em branco | banheiro
      0 0 0

@ A-letubby Funciona agora com a edição - o -Pargumento foi adicionado.
villapx

6

Use eco para inserir a guia para você grep "$(echo -e \\t)"


6

Existem basicamente duas maneiras de resolver isso:

  1. ( Recomendado ) Use sintaxe de expressão regular suportada por grep (1). O grep moderno (1) suporta duas formas de sintaxe de regex POSIX 1003.2: REs básicos (obsoletos) e REs modernos . A sintaxe é descrita em detalhes nas páginas do manual re_format (7) e regex (7) que fazem parte dos sistemas BSD e Linux, respectivamente. O GNU grep (1) também suporta REs compatíveis com Perl, conforme fornecido pela biblioteca pcre (3).

    Na linguagem regex, o símbolo de tabulação é geralmente codificado por \tátomo. O átomo é suportado por expressões regulares estendidas do BSD ( egrep, grep -Eno sistema compatível com BSD), bem como por REs compatíveis com Perl ( pcregrep, GNU grep -P).

    Expressões regulares básicas e REs estendidos do Linux aparentemente não têm suporte para o \t. Por favor, consulte a página de manual do utilitário UNIX para saber qual idioma de regex suporta (daí a diferença entre as expressões regulares sed (1), awk (1) e pcregrep (1)).

    Portanto, no Linux:

    $ grep -P '\t' FILE ...
    

    No sistema BSD:

    $ egrep '\t' FILE ...
    $ grep -E '\t' FILE ...
    
  2. Passe o caractere de tabulação para o padrão. Isso é direto quando você edita um arquivo de script:

    # no tabs for Python please!
    grep -q '   ' *.py && exit 1
    

    No entanto, ao trabalhar em um shell interativo, pode ser necessário confiar nos recursos do shell e do terminal para digitar o símbolo apropriado na linha. Na maioria dos terminais, isso pode ser feito através da combinação de teclas Ctrl+, Vque instrui o terminal a tratar o próximo caractere de entrada literalmente (o Vé para "literalmente"):

    $ grep '<Ctrl>+<V><TAB>' FILE ...
    

    Alguns shells podem oferecer suporte avançado para a digitação de comandos. Assim, no bash (1) as palavras do formulário $'string'são tratadas especialmente:

    bash$ grep $'\t' FILE ...
    

    Observe que, embora seja agradável em uma linha de comando, isso pode produzir problemas de compatibilidade quando o script será movido para outra plataforma. Além disso, tenha cuidado com as cotações ao usar os especiais, consulte o bash (1) para obter detalhes.

    Para o shell Bourne (e não apenas), o mesmo comportamento pode ser emulado usando a substituição de comandos aumentada por printf (1) para construir uma expressão regular adequada:

    $ grep "`printf '\t'`" FILE ...
    

4

grep "$(printf '\t')" trabalhou para mim no Mac OS X


2

use gawk, defina o delimitador de campo como tab (\ t) e verifique o número de campos. Se mais de 1, há / há guias

awk -F"\t" 'NF>1' file

2
Isso é um pouco exagerado e erra a questão. awk /\t/é suficiente para a pergunta do op.
Expiação limitada

2

Uma boa opção é usar 'sed como grep' (como explicado neste tutorial clássico sobre sed ).

sed -n 's/pattern/&/p' file

Exemplos (funciona em bash, sh, ksh, csh, ..):

[~]$ cat testfile
12 3
1 4 abc
xa      c
        a       c\2
1 23

[~]$ sed -n 's/\t/&/p' testfile 
xa      c
        a       c\2

[~]$ sed -n 's/\ta\t/&/p' testfile
        a       c\2

1

+1, que funciona em ksh, dash, etc: use printf para inserir TAB:

grep "$(printf 'BEGIN\tEND')" testfile.txt

Isso não funcionou para mim no Ubuntu Trusty (Bash 4.3.11), mas o seguinte funcionou:grep "$(printf '\t')" testfile.txt
Josh Rumbut

0

A resposta é mais simples. Escreva seu grep e, dentro da citação, digite a tecla tab, funciona bem pelo menos em ksh

grep "  " *

3
primeiro você precisa para gerenciar a entrada de um caractere TAB no seu shell - a maioria das conchas interpretar esta chave como um comando (conclusão)
Kaii


0

Usar o método 'sed-as-grep', mas substituir as guias por um caractere visível de preferência pessoal é o meu método favorito, pois mostra claramente quais arquivos contêm as informações solicitadas e também onde são colocadas nas linhas:

sed -n 's/\t/\*\*\*\*/g' file_name

Se você deseja usar as informações de linha / arquivo ou outras opções grep, mas também deseja ver a substituição visível para o caractere de tabulação, é possível obtê-lo

grep -[options] -P '\t' file_name | sed 's/\t/\*\*\*\*/g'

Como um exemplo:

$ echo "A\tB\nfoo\tbar" > test
$ grep -inH -P '\t' test | sed 's/\t/\*\*\*\*/g'
test:1:A****B
test:2:foo****bar

EDIT: Obviamente, o acima exposto é útil apenas para exibir o conteúdo do arquivo para localizar guias - se o objetivo é manipular guias como parte de uma sessão de script maior, isso não serve a nenhum propósito útil.


0

Isso funciona bem para o AIX. Estou procurando por linhas contendoJOINED<\t>ACTIVE

voradmin cluster status | grep  JOINED$'\t'ACTIVE

 vorudb201   1       MEMBER(g) JOINED        ACTIVE
*vorucaf01   2       SECONDARY JOINED        ACTIVE

0

Você pode querer usar grep "$(echo -e '\t')"

O único requisito é echoser capaz de interpretar escapes de barra invertida.


0

Esses métodos alternativos de identificação binária são totalmente funcionais. E, eu realmente gosto do uso do awk, pois não conseguia me lembrar do uso sintático com caracteres binários únicos. No entanto, também deve ser possível atribuir um valor a uma variável de shell em um estilo portátil POSIX (ou seja, TAB = echo "@" | tr "\100" "\011") e, em seguida, empregá-lo a partir de qualquer lugar, em um estilo portátil POSIX; também (ou seja, grep "$ TAB" nome do arquivo). Embora esta solução funcione bem com TAB, também funcionará bem com outros caracteres binários, quando outro valor binário desejado for usado na atribuição (em vez do valor do caractere TAB para 'tr').


0

A notação $ '\ t' dada em outras respostas é específica do shell - parece funcionar no bash e no zsh, mas não é universal.

NOTA: O seguinte é para o fishshell e não funciona no bash :

No fishshell, pode-se usar um não citado \t, por exemplo:

grep \t foo.txt

Ou pode-se usar as notações hexadecimais ou unicode, por exemplo:

grep \X09 foo.txt
grep \U0009 foo.txt

(essas notações são úteis para caracteres mais esotéricos)

Como esses valores devem ser sem aspas, é possível combinar valores entre aspas e sem aspas por concatenação:

grep "foo"\t"bar"

-4

Você pode digitar

grep \ t foo

ou

grep '\ t' foo

para procurar o caractere de tabulação no arquivo foo. Você provavelmente também pode fazer outros códigos de escape, embora eu só tenha testado \ n. Embora consuma bastante tempo e não esteja claro por que você desejaria, no zsh, você também pode digitar o caractere de tabulação, de volta ao início, grep e colocar a tabulação entre aspas.


-6

Procure espaços em branco muitas vezes [[: space:]] *

grep [[: espaço:]] * '.' '.'

Vai encontrar algo como isto:

'a guia' ..

Estas são aspas simples (') e não duplas (").
É assim que você faz a concatenação no grep. = -)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.