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 theGet-ChildItemorGet-Itemcmdlets; e.g., the equivalent ofbashcommandpattern='*.txt'; echo $patternin 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).Nameor(Get-ChildItem $pattern).FullName(full path). UseGet-ChildItem $pattern | Get-Member -Type Propertiesto see all available properties.
- Note that objects describing the matching files or directories are output by these cmdlets; use their properties as needed, e.g.
The
-Pathparameter 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.
