Escaping slash "\" in grep

11,882

Solution 1

You can use:

grep -v 'H:\\Check' testout.txt > testout2.txt

It is important to use single quotes to avoid excessive escaping of backslash.

Using double quotes equivalent command will be this:

grep -v "H:\\\Check" testout.txt > testout2.txt

EDIT:

\\ in double quotes is equivalent of a single backward slash due to shell expansion that happens in double quotes only. It is evident from these echo commands:

echo "H:\\Check"
H:\Check

echo 'H:\\Check'
H:\\Check

Solution 2

First off, when using grep, you don't need to specify the any characters .* combination. Grep is already built to look for your phrase (Example grepping for he in a file that has a line that says Hi there will return the full line without the need to use .*he.* as your regex does)

Second (And I see anubhava beat me to the punch on this one as I was typing), the backslash escaping works differently depending on your use of quotation marks.

If you are using single quotes, the single backslash will escape the second, so you need two, so your regex will be H:\\Check.

If you are using double quotes (As you are), the backslash will escape the other backslash while the quotes are evaluated, then the resulting backslash will be trying to escape the C (which isn't even close to what we want), so you actually need a third backslash so that they escape correctly.

If you wanted to do it without quotes (which in my opinion isn't very good style, but since you have a single phrase you could if you really wanted to), you would actually need 4 backslashes for a similar reason. The \ would normally let the command continue to the next line, so the first escapes the second, the third escapes the 4th, then there are only 2 when grep is evaluated, which is the escaped correctly.

You should try playing around with Grep some more to see what it's capable of, it can do basically any searching you ever want (and much more that you'll never want) as long as you know the syntax.

Edit: Fixed a little syntax, thanks. I didn't know about that * converts text to italics on these answers.

Share:
11,882
Mahesha999
Author by

Mahesha999

Updated on June 06, 2022

Comments

  • Mahesha999
    Mahesha999 almost 2 years

    I have file with line:

    "H:\Check\WP_20140511_029.mp4"
    

    along with other lines. I want to remove such lines indicating directory at H:\Check. I tried

    grep -v ".*H:\\Check.*" testout.txt > testout2.txt
    

    But it did not delete those lines. Whats wrong with my regex .*H:\\Check.*. regex101 shows that my regex correctly matches the line.

  • Mahesha999
    Mahesha999 almost 7 years
    why we need three slashes \\` inside double quotes and two slashes \` inside single quote. Also why we can left out .*? Shouldnt regex match full line?
  • anubhava
    anubhava almost 7 years
    No grep regex doesn't need to match full line. Just match your known patternn
  • anubhava
    anubhava almost 7 years
    Answer further updated for difference in behavior of single/double quotes handling of backslashes.
  • Daniel H
    Daniel H almost 7 years
    Your “Hi there” example didn’t work quite right; could you please use backticks (`) to indicate a literal string? Outside of those, an asterisk is interpreted as italics instead of a literal asterisk.
  • Mahesha999
    Mahesha999 almost 7 years
    Umm...I thought it should be H:\Check after escaping, not H:\\Check. Why the latter is correct and former is not? Just want to make it more clear for me...
  • anubhava
    anubhava almost 7 years
    Because \C just means escaped C character not a Backslash followed by C
  • anubhava
    anubhava almost 7 years
    Basically presence of a backslash escapes the next character so to enter/match a literal backslash we need to use double backslash.