189

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 ?

1

4 Answers 4

264

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.

3
  • basing on enzotib's answer let me add the following: grep $'\t' foo.txt (but I would usually write fgrep instead of grep) Feb 21, 2013 at 10:16
  • 1
    Perhaps worth noting that BSD (including OSX) grep, lacks the -P option.
    – TextGeek
    Feb 8, 2018 at 18:43
  • 1
    From the man page This is highly experimental and grep -P may warn of unimplemented features. Probably not a good idea to use -P in legacy systems. The printf choice is better Apr 10, 2018 at 18:57
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!).

6
  • 2
    Indeed, I suggest that @enzotib edit the answer to be simply grep $'\t'. Jun 4, 2013 at 12:01
  • It should be stressed that this is a feature of bash and will (silently!) do the wrong thing if executed by some other shell (such as dash, which is the default for shell scripts on Ubuntu and others)
    – xjcl
    Aug 26, 2017 at 14:00
  • @xjcl I never heard of dash being the default on Ubuntu - my Ubuntu always had bash. Can you back that statement up with any source, please?
    – jena
    Sep 30, 2020 at 11:51
  • 1
    @jena bash is the default for interactive sessions. But non-interactive scripts default to /bin/sh which is a link to dash. You can verify this with ls -la /bin/sh
    – xjcl
    Sep 30, 2020 at 20:22
  • @xjcl - interesting, I really never encountered it until now. Anyway, the question is tagged with bash so I think it's "stressed" enough.
    – jena
    Oct 12, 2020 at 14:14
3

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .