2

I'm trying to search for 172.21.134.16 specifically, but I get unwanted rows of others found (ie 172.21.134.161, 162, 163, etc. I just like the results to be 172.21.134.16.

PS C:\Scripts\Ping> Get-ChildItem -path c:\scripts\ping\hostnames.txt -Recurse | select-string -Pattern    '172.21.134.16'

hostnames.txt:119:SMFTBCR0601   172.21.134.16
hostnames.txt:120:SMFTBGT1101   172.21.134.161
hostnames.txt:121:SMFTBGT1102   172.21.134.162
hostnames.txt:122:SMFTBGT1103   172.21.134.163
hostnames.txt:123:SMFTBGT1201   172.21.134.165
hostnames.txt:124:SMFTBGT1202   172.21.134.166
hostnames.txt:125:SMFTBGT1203   172.21.134.167

PS C:\Scripts\Ping> Get-ChildItem -path c:\scripts\ping\hostnames.txt -Recurse | select-string -Pattern   '172.21.134.16'

expecting:

SMFTBCR0601 172.21.134.16

Virtute
  • 21
  • 1

1 Answers1

2

Santiago Squarzon has provided the solution in a comment - -Pattern '\b172\.21\.134\.16\b' - but let me provide background information:

  • Generally, Select-String looks for the -Pattern argument(s) as substring(s) on the individual lines of the files provided as System.IO.FileInfo instance via the pipeline, such as via Get-ChildItem - the same applies to targeting files via Select-String's own -Path and -LiteralPath parameters.[1]

    • As such, even if 172.21.134.16 were searched for verbatim, using -SimpleMatch (see below), it would invariably also match lines that contain … 172.21.134.161 …, for instance, or … 0172.21.134.161 …
  • Select-String interprets its -Pattern argument(s) as regexes (regular expressions) by default.

    • If you want to search by verbatim (literal) substring, add the -SimpleMatch switch.
  • If you want to conditionally match substrings, depending on what characters surround them, using a regex - i.e. not using -SimpleMatch - is a must, such as in this case:

    • In a regex, \b is a word-boundary assertion that ensures that a character / subexpression that follows or precedes it only matches if the immediately preceding / following character isn't a word character (either a letter, a digit, or _ (underscore))

    • However, if the substring you want to constrain this way is to be treated verbatim in the context of a regex, you need to be escape any regex metacharacters in it with \, notably . (which otherwise represents any character). To do so, you have two options:

    • In a literal pattern string, you can individually \-escape all regex metacharacters, which yields Santiago's solution:

       -Pattern '\b172\.21\.134\.16\b'
      
    • If you don't know the verbatim substring ahead of time or don't want to think about which metacharacters you need to escape, use the [regex]::Escape() .NET method:

       -Pattern ('\b' + [regex]::Escape('172.21.134.16') + '\b')
      

[1] It also applies if you provide a file's lines one by one via the pipeline using the Get-Content cmdlet (without the -Raw switch), but this approach to providing input from a file is best avoided for performance reasons.

mklement0
  • 382,024
  • 64
  • 607
  • 775