grep una pestaña en UNIX

418

¿Cómo greptabulo (\ t) en archivos en la plataforma Unix?

Sachin Chourasiya
fuente
53
simplemente use grep "<Ctrl+V><TAB>", funciona (si es la primera vez: escriba, grep "luego presione Ctrl + V combo de teclas, luego presione la tecla TAB, luego escriba "y presione enter, voilà!)
rook
16
ctrl + v es una IDEA REALMENTE MALA! ... sí, puede funcionar desde el comando de la consola, pero NO FUNCIONA PARA TIPARLO EN UN ESCRITO (está a merced del editor, por ejemplo, uso mcedit y ctrl + v NO funciona allí)
THESorcerer
Relacionado, pero no un duplicado: busque pestañas, sin -P, usando 'grep'
Peter Mortensen
Ver también: askubuntu.com/questions/53071/… (vinculado también a continuación)
shiri

Respuestas:

375

Si usa GNU grep, puede usar la expresión regular estilo Perl:

grep -P '\t' *
relajarse
fuente
No parece funcionar en contra de mi patrón. Intentar usar esa sintaxis no imprime nada. (¿Es diferente la variante de Mac OS X?)
futureelite7
2
@futureelite: Según los documentos de Apple ( developer.apple.com/Mac/library/documentation/Darwin/Reference/… ), el programa grep de Mac OS X debería admitir la opción -P. Considere crear una nueva pregunta, en superuser.com.
relajarse
3
Eso es muy bueno para GNU UNIX, pero ¿qué pasa con POSIX Solaris, AIX y HP-UX? Esos no saben nada sobre la -Popción.
torre
21
@rook GNU no es UNIX.
Lily Chung
55
en Mac OSX puedes dar patrón usando -e
Faisal Feroz
314

El truco es usar el signo $ antes de las comillas simples . También funciona para cortar y otras herramientas.

grep $'\t' sample.txt
antimirov
fuente
77
Consejo de salvamento salva vidas! También funciona zsh, por lo que puedo decir. ¿Podría comentar cuál es la semántica de ese $signo?
Romain
2
No funciona si la cadena contiene algo más que '\ t'. ¿Cómo buscarías "\ t" (tab + espacio) por ejemplo?
Raman
66
Raman: Puedes usarlo $'\t'' '. Un ejemplo real que muestra que también funciona con sh (no solo bash, que no está instalado por defecto en Android) es busybox grep -oE '^nodev'$'\t''fuse$' /proc/filesystems.
v6ak
55
Creo que $ '...' es un idioma bash. Probablemente no funciona en sh. No sé sobre csh o tcsh.
Edward Falk
55
De 'man bash': las palabras de la forma $ 'string' se tratan especialmente. La palabra se expande a una cadena, con caracteres de escape con barra invertida reemplazados según lo especificado por el estándar ANSI C. Secuencias de escape de barra invertida, si se descodifican la actualidad, ...
broeni
84

Nunca logré hacer que el metacarácter '\ t' funcione con grep. Sin embargo, encontré dos soluciones alternativas:

  1. Usando <Ctrl-V> <TAB>(presionando Ctrl-V y luego escribiendo pestaña)
  2. Usando awk: foo | awk '/\t/'
SamK
fuente
44
La | awk '/\t/'solución funcionará para todos los shells, plataformas y sistemas.
Samveen
66
+1 para la solución POSIX portátil y que no utilice bashisms, zshism, GNUism y linuxisms.
Jens
1
ctrl-V no es útil si desea copiar y pegar (de sus notas o una secuencia de comandos). Un mejor uso de una solución explícita que tiene un visible '\ t', pestañas literal (es decir, los que se parecen a los espacios en blanco) a menudo se transforman a SPC cuando copypasting ...
plijnzaad
awkfunciona bien aquí, pero en algunas pruebas en mi máquina con archivos muy grandes es aproximadamente un 30% más lento que el uso grep -P. Esto puede ser trivial e irrelevante según el caso de uso, y awkpuede ser mejor simplemente por su legibilidad y portabilidad.
theferrit32
43

De esta respuesta en Ask Ubuntu:

Dígale a grep que use las expresiones regulares definidas por Perl (Perl tiene \tcomo pestaña):

grep -P "\t" <file name>

Use el carácter de tabulación literal:

grep "^V<tab>" <filename>

Use printfpara imprimir un carácter de tabulación para usted:

grep "$(printf '\t')" <filename>
Poo
fuente
1
Verbatim de http://askubuntu.com/a/53096/453741
villapx
ctrl-V no es útil si desea copiar y pegar (de sus notas o una secuencia de comandos). Utilice mejor una solución explícita que tenga una '\ t' visible, las TAB literales (es decir, las que parecen espacios en blanco) a menudo se convierten en SPC cuando se copian las copias
plijnzaad
31

Una forma es (esto es con Bash)

grep -P '\t'

-P activa las expresiones regulares de Perl para que funcione.

Como dice el usuario desenrollar , puede ser específico de GNU grep. La alternativa es insertar literalmente una pestaña allí si el shell, el editor o la terminal lo permiten.

tjmoore
fuente
Opción P desconocida en ksh shell
Sachin Chourasiya 01 de
Como dice desenrollar, puede ser específico de GNU grep. Solo aclarado.
tjmoore 01 de
¿Cómo se agrega una pestaña? ¿No comienza el proceso de autocompletar cuando presionas el botón de tabulación? (que podría funcionar en un script bash pero no en la línea de comando)
AntonioCS
1
@AntonioCS como se señaló anteriormente por SamKrieg, para que el Shell le permita escribir cualquier carácter, simplemente escriba CTRL-v primero. Ver también askubuntu.com/questions/53071/…
Denis Arnaud
2
-P es específico de grep, no de ningún shell. -P debería funcionar en cualquier shell, siempre que GNU grep esté instalado
plijnzaad
13

Otra forma de insertar la pestaña literalmente dentro de la expresión es usar la $'\t'cita menos conocida en Bash:

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

(Tenga en cuenta que si está haciendo coincidir las cadenas fijas, puede usar esto con el modo '-F').

A veces, usar variables puede hacer que la notación sea un poco más legible y manejable:

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

Esto no es exactamente lo que está buscando, pero podría funcionar en su caso

grep '[[:blank:]]'

Equivalente a

grep -P '[ \t]'

Entonces encontrará Space y Tab.

§ Clases de personajes

Tenga en cuenta que no se anuncia en mi man grep, pero aún funciona

$ man grep | grep en blanco | baño
      0 0 0
Steven Penny
fuente
@ A-letubby Ahora funciona con la edición: -Pse agregó el argumento.
villapx
6

Use echo para insertar la pestaña por usted grep "$(echo -e \\t)"

vanjoe
fuente
6

Básicamente hay dos formas de abordarlo:

  1. ( Recomendado ) Utilice la sintaxis de expresión regular compatible con grep (1). Modern grep (1) admite dos formas de sintaxis de expresiones regulares POSIX 1003.2: RE básicas (obsoletas) y RE modernas . La sintaxis se describe en detalle en las páginas de comando man re_format (7) y regex (7) que forman parte de los sistemas BSD y Linux, respectivamente. GNU grep (1) también es compatible con REs compatibles con Perl según lo provisto por la biblioteca pcre (3).

    En lenguaje regex, el símbolo de tabulación generalmente está codificado por \tátomo. El átomo está soportado por BSD extendió expresiones regulares ( egrep, grep -Een el sistema compatible BSD), así como REs compatibles con Perl ( pcregrep, GNU grep -P).

    Aparentemente, tanto las expresiones regulares básicas como los RE extendidos de Linux no tienen soporte para \t. Consulte la página de manual de la utilidad UNIX para saber qué lenguaje de expresiones regulares admite (de ahí la diferencia entre las expresiones regulares sed (1), awk (1) y pcregrep (1)).

    Por lo tanto, en Linux:

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

    En el sistema BSD por igual:

    $ egrep '\t' FILE ...
    $ grep -E '\t' FILE ...
    
  2. Pase el carácter de tabulación al patrón. Esto es sencillo cuando edita un archivo de script:

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

    Sin embargo, cuando trabaje en un shell interactivo, es posible que deba confiar en las capacidades de shell y terminal para escribir el símbolo adecuado en la línea. En la mayoría de los terminales, esto se puede hacer a través de la combinación de teclas Ctrl+ Vque le indica al terminal que trate el siguiente carácter de entrada literalmente ( Ves para "textualmente"):

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

    Algunos shells pueden ofrecer soporte avanzado para la composición tipográfica de comandos. Tal, en bash (1) las palabras del formulario $'string'se tratan especialmente:

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

    Sin embargo, tenga en cuenta que, si bien es agradable en una línea de comandos, esto puede producir problemas de compatibilidad cuando el script se moverá a otra plataforma. Además, tenga cuidado con las citas cuando use las ofertas especiales, consulte bash (1) para obtener más detalles.

    Para el shell Bourne (y no solo) se puede emular el mismo comportamiento utilizando la sustitución de comandos aumentada por printf (1) para construir la expresión regular adecuada:

    $ grep "`printf '\t'`" FILE ...
    
Mike Volokhov
fuente
4

grep "$(printf '\t')" funcionó para mí en Mac OS X

kumar303
fuente
2

use gawk, establezca el delimitador de campo en tab (\ t) y verifique el número de campos. Si hay más de 1, entonces hay pestañas

awk -F"\t" 'NF>1' file
ghostdog74
fuente
2
Esto es un poco exagerado, y pierde la pregunta. awk /\t/es suficiente para la pregunta del operador.
Expiación limitada el
2

Una buena opción es usar 'sed as grep' (como se explica en este tutorial clásico de sed ).

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

Ejemplos (funciona en 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
fuente
1

+1 forma, que funciona en ksh, dash, etc.: use printf para insertar TAB:

grep "$(printf 'BEGIN\tEND')" testfile.txt
Zsigmond Lőrinczy
fuente
Esto no funcionó para mí en Ubuntu Trusty (Bash 4.3.11), lo siguiente sí funcionó:grep "$(printf '\t')" testfile.txt
Josh Rumbut
0

La respuesta es más simple. Escriba su grep y dentro de la cita escriba la tecla de tabulación, funciona bien al menos en ksh

grep "  " *
YullyBear
fuente
3
primero debe administrar ingresar un carácter TAB en su shell - la mayoría de los shells interpretan esta clave como un comando (finalización)
Kaii
0

En ksh solía

grep "[^I]" testfile
AIXroot
fuente
0

Usar el método 'sed-as-grep', pero reemplazar las pestañas con un carácter visible de preferencia personal es mi método favorito, ya que muestra claramente qué archivos contienen la información solicitada y también dónde se coloca dentro de las líneas:

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

Si desea hacer uso de la información de línea / archivo u otras opciones grep, pero también quiere ver el reemplazo visible para el carácter de tabulación, puede lograr esto al

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

Como ejemplo:

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

EDITAR: Obviamente, lo anterior solo es útil para ver el contenido del archivo para localizar pestañas --- si el objetivo es manejar pestañas como parte de una sesión de secuencia de comandos más grande, esto no sirve para ningún propósito útil.

Silasvb
fuente
0

Esto funciona bien para AIX. Estoy buscando líneas que contenganJOINED<\t>ACTIVE

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

 vorudb201   1       MEMBER(g) JOINED        ACTIVE
*vorucaf01   2       SECONDARY JOINED        ACTIVE
gruñido
fuente
0

Es posible que desee utilizar grep "$(echo -e '\t')"

El único requisito es echoser capaz de interpretar escapes de barra invertida.

kshpolvind
fuente
0

Estos métodos alternativos de identificación binaria son totalmente funcionales. Y, realmente me gusta que alguien esté usando awk, ya que no podía recordar el uso sintáctico con caracteres binarios individuales. Sin embargo, también debería ser posible asignar un valor a una variable de shell de una manera portátil POSIX (es decir, TAB = echo "@" | tr "\100" "\011"), y luego emplearlo desde allí en todas partes, de manera portátil POSIX; también (es decir, nombre de archivo grep "$ TAB"). Si bien esta solución funciona bien con TAB, también funcionará bien con otros caracteres binarios, cuando se utiliza otro valor binario deseado en la asignación (en lugar del valor para el carácter TAB a 'tr').

odoncaoa
fuente
0

La notación $ '\ t' dada en otras respuestas es específica de shell: parece funcionar en bash y zsh pero no es universal.

NOTA: Lo siguiente es para el fishshell y no funciona en bash :

En el fishshell, se puede usar un sin comillas \t, por ejemplo:

grep \t foo.txt

O uno puede usar las notaciones hexadecimales o unicode, por ejemplo:

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

(estas anotaciones son útiles para más caracteres esotéricos)

Dado que estos valores deben estar sin comillas, se pueden combinar valores con comillas y sin comillas por concatenación:

grep "foo"\t"bar"
Raman
fuente
-4

Puedes escribir

grep \ t foo

o

grep '\ t' foo

para buscar el carácter de tabulación en el archivo foo. Probablemente también pueda hacer otros códigos de escape, aunque solo he probado \ n. Aunque es bastante lento y no está claro por qué querría hacerlo, en zsh también puede escribir el carácter de tabulación, volver al principio, grep y encerrar la tabulación con comillas.

Salmuera accidental
fuente
-6

Busque espacios en blanco muchas veces [[: espacio:]] *

grep [[: espacio:]] * '.' '.'

Encontrará algo como esto:

'la tabla' ..

Estas son comillas simples ('), y no dobles (").
Así es como se hace la concatenación en grep. = -)

Caio Argolo
fuente