Extract words from filename delineated by underscores and spaces in Powershell

I am trying to extract two words from filenames. The names have the format:

__XXXXXXXX_XXX_XXXXXXX_XXXX_XXXXX_XXXX XXX_Aircraft 017_XXXXXXXX-XXXXXXX_XXXXXXX-XXXXXXX-XXXXXX-01Apr2021-XXXXX

With the X's being replaced with different words. I need to extract the aircraft number and the date so that I can rename the files with just that information. Using help from this site I have tried the following to isolate the aircraft number:

$names = gci -Path "H:\Path\to\Logs" *.log -Recurse | select @{n="Name"; e={if ($_.Name -match "Aircraft (\w+)") { 
  $matches[1] }}}

However, it doesn't seem to give me the match I need. However, I am very inexpert in programming and may be going down the wrong path. My hope is that the same logic used to isolate the aircraft number also applies for the date.

1 answer

  • answered 2021-07-27 15:49 mklement0

    # Create a sample file.
    $file = New-Item '__XXXXXXXX_XXX_XXXXXXX_XXXX_XXXXX_XXXX XXX_Aircraft 017_XXXXXXXX-XXXXXXX_XXXXXXX-XXXXXXX-XXXXXX-01Apr2021-XXXXX'
    
    # Substitute your `Get-ChildItem` command for $file
    $file |
     Rename-Item -WhatIf -NewName {
       if ($_.Name -match '_(Aircraft \w+?)_.+(\d{2}[a-z]{3}\d{4})-') {
         # Synthesize the new file name from the extracted substrings.
         '{0} - {1}' -f $Matches[1], $Matches[2]
       } else {
         # Input file name didn't match, (effectively) do nothing.
         $_.Name
       }
     }
    

    Note: The -WhatIf common parameter in the command above previews the operation. Remove -WhatIf once you're sure the operation will do what you want.

    For an explanation of the regex used with the -match operator above, see this regex101.com page.[1]

    The above uses two capture groups ((...)) to capture the substrings of interest, which can be accessed via indices 1 and 2 of the automatic $Matches variable.

    -f, the format operator is then used to build the output file name from the captured substrings. Tweak the LHS format string as needed.

    Thanks to -WhatIf, you'll see output such as the following, which is the preview of what would happen when you remove -WhatIf - note the new file name in the Destination: path:

    What if: Performing the operation "Rename File" on target 
    "Item: /tmp/__XXXXXXXX_XXX_XXXXXXX_XXXX_XXXXX_XXXX XXX_Aircraft 017_XXXXXXXX-XXXXXXX_XXXXXXX-XXXXXXX-XXXXXX-01Apr2021-XXXXX
    Destination: /tmp/Aircraft 017 - 01Apr2021".
    

    Note how a script block ({ ... }) is passed as an argument to Rename-Item's -NewName parameter, which then acts on each input file via the automatic automatic $_ variable and outputs the argument value to use for the input object at hand. Such script blocks are called delay-bind script blocks.


    [1] Note that even though regex101.com, a site for visualizing, explaining and experimenting with regexes, doesn't support the .NET regex engine used by PowerShell, choosing a similar engine, such as Java's, usually exhibits the same behavior, at least fundamentally.

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum