Home > front end >  Powershell - Need to take only file name with a specific pattern and ignore the rest
Powershell - Need to take only file name with a specific pattern and ignore the rest

Time:07-29

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 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.

CodePudding user response:

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

  • Related