Search code examples
powershellloopsbatch-rename

Copying a document into a folder and then renaming it with part of the folder name


I have a large set of folders in Windows named like this:
firstname lastname_xxxxxxx_ where xxxxxxx is a numeric ID.

All these sub-folders are in a folder called "T:\Tests2022"
The directories look like this:

John Smith_12345678_
Mary Scott_87945687_
William Tell_9875348_
Jane Doe_57982388_

e.g. a complete path is T:\Tests2022\John Smith_12345678_

I have a document "testscript.txt" that I want to move into each of these folders. This file also sits in the root of "Tests2022" (i.e. T:\Tests2022\testscript.txt)

However, I would like to prepend "Firstname_" to the file. (e.g. in the first folder the file would be called "T:\Tests2022\John Smith_12345678_\John_testscript.txt").

Ideally, if the world were perfect, the file would be named "john Smith_tescript.txt")

Simply moving the file in the CMD line is easy: e.g. 'Moveit.bat' contains

    for /D %%a in (".\*.*") do xcopy /y /d ".\testscript.txt" "%%a\"

I could do this manually, but I have to do something similar every two weeks with a different list of test directories so that a macro would be ideal.

I need help to move this to PowerShell and then use PowerShell to parse and collect text either to the first space (between the firstname/lastname pair) or the first underscore.


Solution

  • Inline comments should help to understand the logic. If you want to learn something new you should look for yourself the commands being used in the script.

    This link https://regex101.com/r/h0SYVz/1 should explain this:

    $_.Name -replace '(?<=_).+'
    

    $targetFile = 'T:\Tests2022\testscript.txt'
    
    # Enumerate all Directories in Test2022
    Get-ChildItem T:\Tests2022\ -Directory | ForEach-Object {
        # if this Subdirectory has the `testscript.txt` in it
        if($_ | Get-ChildItem -Filter *testscript.txt) {
            # go to the next Directory, nothing to do here
            return
        }
    
        # if this Subdirectory doesn't have the file,
        # extract everything up until the underscore for the folder name
        # and concatenate with `testscript.txt`
        $name = ($_.Name -replace '(?<=_).+') + 'testscript.txt'
        # Join this folder's absolute path with the new file name
        $destination = Join-Path $_.FullName -ChildPath $name
        # now we can copy the `.txt` file into this folder
        Copy-Item $targetFile -Destination $destination
    }