powershell to move files based on part of file name

后端 未结 3 1035
夕颜
夕颜 2020-12-17 03:54

I have thousands of files like the following in a directory called D:\\queries\\

#TIM_DV_ORDERINQUERY.SQL
#TIM_QA_ORDERINQUERY.SQL
#TIM_P1_ORDERINQUERY.SQL
         


        
相关标签:
3条回答
  • 2020-12-17 04:09

    This makes use of the FileInfo class, to get information pertaining to the directory.

    $SourceFolder = "G:\queries\"
    $targetFolder = "G:\queries\"
    
    # Find all files matching *.sql in the folder specified
    Get-ChildItem -Path $SourceFolder -Filter *.sql | ForEach-Object {
    
        # Combine the source filename and target directory
        # The source filename has all instances of _ replaced with \
        # Cast the resulting string to a FileInfo object to take advantage of extra methods
        [System.IO.FileInfo]$destination = (Join-Path -Path $targetFolder -ChildPath $_.Name.replace("_","\"))
    
        # Create the directory if it doesn't already exits
        if (!(Test-Path) $destination.Directory.FullName)
        { 
            New-item -Path $destination.Directory.FullName -ItemType Directory 
        }
    
        # Copy the source to the target directory
        copy-item -Path $_.FullName -Destination $Destination.FullName 
    }
    
    0 讨论(0)
  • 2020-12-17 04:16

    You'll probably want to use a regular expression for this. That will help to ensure that only files that match the specified pattern get moved, and you don't have any "accidents."

    # 1. Get a list of files in the d:\queries folder
    $FileList = Get-ChildItem -Path d:\queries;
    
    # 2. Parse file names, create folder structure, and move files
    foreach ($File in $FileList) {
        $File.Name -match '(?<folder>.*?)(?:_)(?<subfolder>\w{2})(?:_)(?<filename>.*)';
        if ($matches) {
            $Destination = 'd:\queries\{0}\{1}\{2}' -f $matches.folder, $matches.subfolder, $matches.filename;
            mkdir -Path (Split-Path -Path $Destination -Parent) -ErrorAction SilentlyContinue;
            Move-Item -Path $File.FullName -Destination $Destination -WhatIf;
        }
        $matches = $null
    }
    
    0 讨论(0)
  • 2020-12-17 04:30

    I modified David's version a bit and this works like I wanted. Thanks David for your help.

    $SourceFolder = "D:\queries\"
    $targetFolder = "G:\queries\"
    $numFiles = (Get-ChildItem -Path $SourceFolder -Filter *.TXT).Count
    $i=0
    
    clear-host;
    Write-Host 'This script will copy ' $numFiles ' files from ' $SourceFolder ' to ' $targetFolder
    Read-host -prompt 'Press enter to start copying the files'
    
    Get-ChildItem -Path $SourceFolder -Filter *.TXT | %{ 
        [System.IO.FileInfo]$destination = (Join-Path -Path $targetFolder -ChildPath $_.Name.replace("_","\"))
    
       if(!(Test-Path -Path $destination.Directory )){
        New-item -Path $destination.Directory.FullName -ItemType Directory 
        }
        [int]$percent = $i / $numFiles * 100
    
        copy-item -Path $_.FullName -Destination $Destination.FullName
        Write-Progress -Activity "Copying ... ($percent %)" -status $_  -PercentComplete $percent -verbose
        $i++
    }
    Write-Host 'Total number of files read from directory '$SourceFolder ' is ' $numFiles
    Write-Host 'Total number of files that was copied to '$targetFolder ' is ' $i
    Read-host -prompt "Press enter to complete..."
    clear-host;
    
    0 讨论(0)
提交回复
热议问题