1
votes

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

3

3 Answers

1
votes

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.

1
votes

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 like foopatch_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.
0
votes

Get-ChildItem -Path $path -Include "patch"