¿Cómo buscar pestañas sin usar pestañas literales y por qué no funciona?


146

Cuando busco pestañas en un archivo con (e) grep, uso la pestaña literal ( ^v + <tab>). No puedo utilizar \tcomo reemplazo de pestañas en expresiones regulares. Con, por ejemplo, sed, esta expresión funciona muy bien.

Entonces, ¿hay alguna posibilidad de usar un reemplazo no literal <tab>y cuáles son los antecedentes de un trabajo / no interpretado \t?


Respuestas:


206

grep está utilizando expresiones regulares según lo definido por POSIX . Por alguna razón POSIX no se ha definido \tcomo pestaña.

Tienes varias alternativas:

  • dile a grep que use las expresiones regulares definidas por perl (perl tiene \tcomo tabulador):

    grep -P "\t" foo.txt

    la página del manual advierte que esta es una característica "experimental". al menos \tparece funcionar bien. pero las características más avanzadas de perl regex pueden no ser

  • use printf para imprimir un carácter de tabulación para usted:

    grep "$(printf '\t')" foo.txt
  • usa el carácter de tabulación literal:

    grep "^V<tab>" foo.txt

    es decir: escriba grep ", luego presione ctrl+v, luego presione tab, luego escriba " foo.txt. Al presionar ctrl+vel terminal, la siguiente tecla se tomará al pie de la letra. eso significa que el terminal insertará un carácter de tabulación en lugar de activar alguna función vinculada a la tecla de tabulación.

  • use la función de cita ansi c de bash:

    grep $'\t' foo.txt

    Esto no funciona en todos los depósitos.

  • usa awk:

    awk '/\t/'
  • usar sed:

    sed -n '/\t/p'

Consulte el artículo de Wikipedia sobre expresiones regulares para obtener una descripción general de las clases de caracteres definidas en POSIX y otros sistemas.


basándome en la respuesta de enzotib, permítanme agregar lo siguiente: grep $'\t' foo.txt(pero normalmente escribiría en fgreplugar de grep)
Walter Tross

Necesitaba esto, combinado con el uso del valor de una variable de entorno. He utilizado grep "$(printf '\t')${myvar}" foo.txt. Funcionó bien. Con algunos intentos, no pude conseguir que funcionara la última forma.
sancho.s

1
¿Hay alguna razón por la que plain grepno pueda interpretarse silenciosamente \tcomo tab? ¿POSIX requiere que eso \tsignifique algo más? ¿Quizás se supone que debe coincidir solo con un literal \ seguido de un t?
Aaron McDaid el

Quizás valga la pena señalar que BSD (incluido OSX) grep, carece de la opción -P.
TextGeek

Desde la página de manual This is highly experimental and grep -P may warn of unimplemented features.Probablemente no sea una buena idea para usar -Pen sistemas heredados. La printfelección es mejor
Avindra Goolcharan

13

Bash no es exactamente la respuesta que le gustaría escuchar, pero bash proporciona un posible uso de secuencias de escape

command | grep $'\t'

(¡no lo ponga entre comillas dobles!).


1
no hay necesidad de -E (lo que se busca no es regex). Tampoco hay necesidad de canalizar desde un comando. Dicho esto, gracias por señalar esta característica bastante olvidada de bash (cadenas de comillas simples precedidas por $)
Walter Tross

2
De hecho, sugiero que @enzotib edite la respuesta para que sea simple grep $'\t'.
Teemu Leisti

Debería enfatizarse que esta es una característica de bash y que hará (¡en silencio!) Hacer lo incorrecto si es ejecutada por otro shell (como dash, que es el valor predeterminado para los scripts de shell en Ubuntu y otros)
xjcl


1

Siempre se puede recurrir al uso del código hexadecimal ascii para la pestaña:

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

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

$ grep $'\x9' input.txt                                            
one two
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.