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
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
}
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
}
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;