191

When I search for tabs in a file with (e)grep I use the litteral tab (^v + <tab>). I can not utilize \t as a replacement for tabs in regular expressions. With e.g. sed this expression works very well.

So is there any possibility to use a non-litteral replacement for <tab> and what are the backgrounds for a non working / not interpreted \t ?

smci
  • 107
Lasall
  • 3,733

4 Answers4

265

grep is using regular expressions as defined by POSIX. For whatever reasons POSIX have not defined \t as tab.

You have several alternatives:

  • tell grep to use the regular expressions as defined by perl (perl has \t as tab):

    grep -P "\t" foo.txt
    

    the man page warns that this is an "experimental" feature. at least \t seems to work fine. but more advanced perl regex features may not.

  • use printf to print a tab character for you:

    grep "$(printf '\t')" foo.txt
    
  • use the literal tab character:

    grep "^V<tab>" foo.txt
    

    that is: type grep ", then press ctrl+v, then press tab, then type " foo.txt. pressing ctrl+v in the terminal causes the next key to be taken verbatim. that means the terminal will insert a tab character instead of triggering some function bound to the tab key.

  • use the ansi c quoting feature of bash:

    grep $'\t' foo.txt
    

    this does not work in all shells.

  • use awk:

    awk '/\t/'
    
  • use sed:

    sed -n '/\t/p'
    

See the wikipedia article about regular expressions for an overview of the defined character classes in POSIX and other systems.

Lesmana
  • 18,754
19

It is not exactly the answer you would want to hear, but a possible use of escape sequences is provided by bash

command | grep $'\t'

(do not put it into double quotes!).

Ravexina
  • 57,256
enzotib
  • 96,093
4

awk '/\t/' is my favorite workaround:

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

Output: a\t.

2

One can always resort to using ascii hex-code for tab:

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

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

$ grep $'\x9' input.txt                                            
one two