views:

1194

answers:

2

In my PowerShell script, I'm running Select-String over a number of files, looking for a string passed into it via a variable ($id):

foreach ($file in (ls "path\to\files")) {
    $found = $false
    $found = Select-String -Path $file $id -Quiet
    if ($found) {
        break
    }
}

Unfortunately, the $id variable sometimes things like "\C" or "\T", which Select-String tries to interpret as escape sequences. These are not valid escape sequences, so Select-String throws an error. They are not intended to be escape sequences (e.g., it could be part of a file path such as "C:\Test"), so how can I prevent PowerShell/Select-String from interpreting them as such? I've tried using parentheses around $id with no luck.

+6  A: 

Use the static escape() method, it instructs the regular expression engine to interpret these characters literally rather than as metacharacters:

$id = [regex]::escape($id)

You can also turn the command to a one liner (-path can take a collection of files):

Select-String -Path path\to\files\* -Pattern ([regex]::escape($id)) -Quiet

Shay Levy
This cracked it, thanks a lot!!
alastairs
I'd give another +1 for the one-liner, if I could up-vote twice. :-)
Tomalak
Sadly the one-liner doesn't work for the specific situation - I cut out a -Filter and a -Recurse parameter
alastairs
In that case:dir path\to\files -r | Select-String -Pattern ([regex]::escape($id)) -Quiet -list
Shay Levy
A: 

If the $id string already contains something like TAB when it's passed to you then I'm not aware of a built in method to safely escape it back to "\t". You need to make sure your script is passed the correct string in the first place. I.e. it needs to passed 0x5C74 (\t) not 0x09 (TAB). So the escaping needs to be done when the the search string is first defined.

Regex.Escape will escape TAB -> \t but will also escape any of these characters that have meaning within regular expressions:

\, *, +, ?, |, {, [, (,), ^, $,., #, and white space

e.g.   . -> \.

it depends