grep uma guia no UNIX

418

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

Sachin Chourasiya
fonte
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' *
descontrair
fonte
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
antimirov
fonte
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/'
SamK
fonte
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>
Cocô
fonte
1
Verbatim de http://askubuntu.com/a/53096/453741
villapx
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.

tjmoore
fonte
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`
Alois Mahdal
fonte
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
Steven Penny
fonte
@ 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)"

vanjoe
fonte
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 ...
    
Mike Volokhov
fonte
4

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

kumar303
fonte
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
ghostdog74
fonte
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
Julio
fonte
1

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

grep "$(printf 'BEGIN\tEND')" testfile.txt
Zsigmond Lőrinczy
fonte
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 "  " *
YullyBear
fonte
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

No ksh eu usei

grep "[^I]" testfile
AIXroot
fonte
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.

Silasvb
fonte
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
gruic
fonte
0

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

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

kshpolvind
fonte
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').

odoncaoa
fonte
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"
Raman
fonte
-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.

Salmoura acidental
fonte
-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. = -)

Caio Argolo
fonte