Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I've created simple text file named "T" to test the unusual behavior of grep:

    1 Debug
    2 debug
    3 determined
    4 Determined

Tried different syntax:

    $ grep De T
        1 Debug
        4 Determined
    $ grep de T
        2 debug
        3 determined
    $ grep Determined T
        4 Determined
    $ grep determined T
        3 determined
    $ grep Debug T
        1 Debug
    $ grep debug T
        2 debug
    $ grep [D]ebug T          # Why result is 2-nd line???
        2 debug
    $ grep [Dd]ebug T         # Why result is only one 2-nd line???
        2 debug
    $ grep [Dd]e T
        1 Debug
        2 debug
        3 determined
        4 Determined
    $ grep [d]e T
        2 debug
        3 determined
    $ grep [d]ebug T
        2 debug
    $ grep "[D]ebug" T
        1 Debug
    $ grep "[Dd]ebug" T
        1 Debug
        2 debug
    $ grep [\D]ebug T         # Why result is 2-nd line???
        2 debug
    $ grep --version
        grep (GNU grep) 2.16

As you can see, almost every grep call returns correct result, but $ grep [D]ebug T, $ grep [Dd]ebug T, $ grep [\D]ebug T return wrong results. Why is this happening?

share|improve this question
    
I'm fairly sure that you should use grep [D,d] to grep for both cases of d. (Or use grep's case-insensitive option.) –  Wolfer Feb 1 at 15:23
    
@Wolfer, I think that you are wrong: I added 5 ,ebug line into T and grep [D,d] T included 5 ,ebug into output. It treated ',' as an additional substitute character - like 'D' and 'd'. –  vedg Feb 1 at 15:42

1 Answer 1

up vote 7 down vote accepted

I'm guessing that you probably have a file or directory called debug in your current working directory:

 $ ls -l
total 8
-rw-r--r--   1 jay   wheel   58 Feb  1 05:01 T
 $ grep [D]ebug T
    1 Debug
 $ grep [Dd]ebug T
    1 Debug
    2 debug

 $ touch debug
 $ ls -l
total 8
-rw-r--r--  1 jay  wheel  58 Feb  1 05:01 T
-rw-r--r--  1 jay  wheel   0 Feb  1 05:05 debug

 $ grep [D]ebug T
    2 debug
 $ grep [Dd]ebug T
    2 debug

I commend you on this excellent illustration why you must always escape shell metacharacters.

Update to clarify what's going on: I'm assuming you, like I, are using an OS with a case-insensitive filesystem (e.g. a Mac). When you execute the command, your shell performs a number of expansions on it before actually executing grep. One of those is filename expansion in which square brackets provide alternations:

[Dd]ebug on a case-sensitive filesystem would expand to either Debug debug, Debug or debug depending on what files it could match. Since it only matched the file debug, your command became:

grep debug T

If you remove that file and do touch Debug, you'll see the output of your command change because it will be interpolated as

grep Debug T

Without the debug file in your directory, your shell tries to interpolate the brackets but fails without a match so it happens to pass the argument through unchanged.

share|improve this answer
    
Yes, you are correct. Thanks. I'm not really familiar with grep, just an amateur :) –  vedg Feb 1 at 13:30
    
But I still don't understand what is going on here. What is exactly the reason for grep to return 2 debug? –  vedg Feb 1 at 13:42
1  
@user1673789 Maybe you have nocaseglob enabled. You could check with shopt -p|grep nocaseglob. If enabled, the [D]ebug first matches your file named debug and then is passed as an argument to grep. That's why you should always use single quotes (and/or escape) with regex on the command prompt. –  forcefsck Feb 1 at 14:56
    
I clarified above what happens during the shell's filename expansion. –  Jay Allen Feb 1 at 15:05
1  
@terdon, nocaseglob is relevant here. Auto-completion is case-insensitive, because nocaseglob is enabled, as @forcefsck suggested. –  vedg Feb 1 at 16:01

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.