Home > Net >  how to copy files based on filename lenght using powershell
how to copy files based on filename lenght using powershell

Time:03-30

I need to batch copy a sort of file extensions from subfolders to specific folders for each location.

All folders have a 6 digit number let's say folder Rood folder: BATCH

Subfolder 1: 000000
Subfolder 2: 111111 

despite their extensions, most files have the name as the subfolder but some of them may have extra alphanumeric characters, therefore the script should grab only the ones that are not larger than 6 digits.

Example Subfolder1: 000000.pdf 000000.eps the script would need to grab all pdf within subfolders and export them to a PDF exclusive new folder, and the same would apply for eps files.

I know nothing about powershell but I know that something like this would work for an specific subfolder but I'm still missing the parts where it distributes them to a new PDFONLY and EPSONLY folders and the fact the I want to apply this to all the folders whiting the root folder.

Get-ChildItem -Path "C:\BATCH\*" -Include *.pdf,*.eps -Recurse | Copy-Item -Destination D:\

CodePudding user response:

You can use Group-Object to group all the files by their extension and then loop over each group of objects, create a new folder with the desired name and lastly copy all objects of each group to their folders.

$target = 'D:\' # Set destination here

Get-ChildItem -Path C:\BATCH\* -Include *.py, *.ps1 -Recurse |
    Group-Object Extension | ForEach-Object {
        # Example of `$folderName` would be `PDF ONLY`
        $folderName = '{0} ONLY' -f $_.Name.TrimStart('.').ToUpper()
        $destination = Join-Path $target -ChildPath $folderName
        # If the `$destination` folder doesn't exist
        if(-not (Test-Path $destination)) {
            # Create it
            $null = New-Item $destination -ItemType Directory
        }
        Copy-Item -LiteralPath $_.Group.FullName -Destination $destination
    }

CodePudding user response:

Similar to Santiago's answer but with an extra filter and without grouping you can do this:

$destination = 'X:\somewhere'

Get-ChildItem -Path "C:\BATCH" -Include '*.pdf','*.eps' -File -Recurse |
Where-Object {$_.BaseName -match '^\d{6}$' } |   # filter files with a BaseName of just 6 digits
ForEach-Object {
    $targetPath = Join-Path -Path $destination -ChildPath ('{0}ONLY' -f $_.Extension.TrimStart(".").ToUpper())
    # make sure the target path exists
    # for directories, using the -Force switch either creates a new folder 
    # or returns the DirectoryInfo object of an existing folder.
    $null = New-Item -Path $targetPath -ItemType Directory -Force
    $_ | Copy-Item -Destination $targetPath
}
  • Related