I have a script that read a file name from path location and then he takes only the numbers and do something with them. could be more than one file in the path
An example for file:
Patch_1348968.vip
Patch_1348968_v1.vip
Patch_1348968_v2.Zip
It takes the number 1348968.
The code that do that is:
$compressedfiles = Get-ChildItem -path $FilesPath\* -Include "*.vip", "*.zip", "*cab"
foreach ($file in $compressedfiles) {
$PatchNumber = ""
$PatchNumber = $file.Name -replace '.*[-_](\d ).*', '$1'
more code....
}
The goal is to ignore (continue to the next file) while the pattern is not as patch_######### An example to files I want to ignore: patch-8.6.22 (DA GUI CU 1351661 1344344).zip
Any idea how to do it? Thanks
CodePudding user response:
Your regex is too permissive to exclude the files that are not of interest.
Based on the examples, including in later comments, and your description, the following would work:
# Simulated Get-ChildItem output.
$compressedfiles = [System.IO.FileInfo[]] @(
'patch-8.6.22 (DA GUI CU 1351661 1344344).zip',
'Patch_1348968.vip'
'Patch_1348968_v1.vip',
'Patch_1348968_v2.Zip',
'patch-1234567.zip',
'patch_7654321-V9.zip'
'patch-7654329-V10.zip',
'patch_42424242_abc453.zip',
'[email protected]',
'Patch_1348968_copy.Zip'
)
foreach ($file in $compressedfiles) {
if ($file.Name -notmatch '^patch[-_](\d )(?:[-_][\w] @?\d*)?\.\w{3}$') {
Write-Verbose -Verbose "Skipping: $($file.Name)"
continue
}
$patchNumber = $Matches[1] # Get the number that the capture group matched.
$patchNumber # Sample output.
# ...
}
The above uses the -notmatch
operator and the automatic $Matches
variable instead of -replace
, because the latter returns the input string as-is if its regex operand doesn't match (while you can compare the result to see if it is the same as the input string to infer whether -replace
found at least one match, the above strikes me as conceptually clearer).
For an explanation of the regex and the ability to experiment with it, see this regex101.com page.
CodePudding user response:
Use the -match
operator to test if a string matches a given pattern. Extract the version number using a capture group (...)
in the RegEx.
foreach ($file in $compressedfiles) {
if( $file.Name -match '^patch_(\d )' ) {
$PatchNumber = $matches[1]
# more code....
}
}
- The condition in the
if
statement evaluates to$true
, when the pattern matches. - The pattern:
^
makes sure we match at the start of the file name, so names likefoopatch_12345.zip
won't match.patch_
matches literally (case-insensitively by default)(
starts a capture group\d
matches one or more digits)
ends the capture group
- For more information see the regex101 demo.
- Using the automatic
$matches
variable, which contains the full match at index 0 and the matched values of any capture groups at subsequent indices, we extract the patch number. So$matches[1]
is the value that matches the pattern\d
within the parentheses.
CodePudding user response:
Get-ChildItem -Path $path -Include "patch"