Home > Enterprise >  Get path based on regex Powershell
Get path based on regex Powershell

Time:01-08

I queried the registry to get a file path I am looking for. However, I need to go one directory lower to retrieve some file info I need. The pattern I am trying to match against is Officexx or OFFICExx. I can't seem to get the path I need.

Found path from registry: C:\Program Files\Microsoft Office

What I need is: C:\Program Files\Microsoft Office\Officexx

Code:

$base_install_path = "C:\Program Files\Microsoft Office";
$full_install_path = $base_install_path '\Office[\d .*]'
Write-Output $full_install_path;  

This returns:

C:\Program Files\Microsoft Office\Office[\d .*] 

Desired output:

C:\Program Files\Microsoft Office\Office15

Not this could be any two digit # ^^

CodePudding user response:

Building on Santiago Squarzon's helpful comment:

# Find all child directories matching the given wildcard pattern, if any.
Get-ChildItem -Directory -Path "$base_install_path\Office[0-9][0-9]*"
  • Unlike POSIX-compatible shells such as bash, PowerShell does not support automatic globbing of unquoted strings (pattern matching against file names, known as filename expansion) and instead requires explicit use of the Get-ChildItem or Get-Item cmdlets; e.g., the equivalent of bash command pattern='*.txt'; echo $pattern in PowerShell is $pattern='*.txt'; Get-ChildItem -Path $pattern

    • Note that objects describing the matching files or directories are output by these cmdlets; use their properties as needed, e.g. (Get-ChildItem $pattern).Name or (Get-ChildItem $pattern).FullName (full path). Use Get-ChildItem $pattern | Get-Member -Type Properties to see all available properties.
  • The -Path parameter of these cmdlets expects a PowerShell wildcard expression to perform the desired matching, and the expression in the command at the top matches exactly two digits ([0-9][0-9]), followed by zero or more characters (*), whatever they may be (potentially including additional digits).


Given that wildcard patterns support only one, non-specific duplication construct, namely the aforementioned *, matching a specific range of digits - such as 1 or 2 at most or a specific count - such as exactly two - requires post-filtering based on a regex (which is what you tried to use):

# Find all child directories matching the given regex, if any.
# Matches 'Office' at the start of the name (^),
# followed by 1 or 2 ({1,2}) digits (\d), 
# followed by at least non-digit (\D), if any (?)
Get-ChildItem -Directory -LiteralPath $base_install_path |
  Where-Object Name -match '^Office\d{1,2}\D?'

As for what you tried:

  • [\d .*] is a regex, but you probably meant \d.*

  • Inside a character-range/set expression ([...]), . and * are used verbatim, i.e. they are not metacharacters and match literal . and * characters.

CodePudding user response:

Get-ChildItem -Path 'C:\Program Files\Microsoft Office\' -Directory | 
    Where-Object { $_.Name -match 'Office\d ' }

In your regex, [] is a character class which means [\d .*] is not "one or more numbers" it's "a backslash OR d OR plus OR dot OR asterisk".

PS C:\> "d \" -match "[\d ]"
True

Not what you were looking for.

  •  Tags:  
  • Related