This is my first question here and i'm new to powershell.
I have a folder $home\Devoluciones\ with several files named DtoXXXYYYYMM.dat where XXX is a company number, YYYY is the current year and MM stands for current month.
What i need to do is to copy those files to folders named with the company number, for example if i have Dto509201506.dat and Dto908201506.dat i need to copy those files to $destination\509\ and $destination\908\ respectively.
Till now i have the following code:
#List the items and send to a.txt
ls $home\Devoluciones\Dto*.dat | select -exp Name > $home\a.txt
#From a.txt keep first 6 characters and send to b.txt
Get-Content $home\a.txt | foreach {$_.remove(6)} | Add-Content $home\b.txt
#From b.txt replace Dto with "" and send to c.txt
Get-Content $home\b.txt | foreach {$_ -replace "Dto",""} | Add-Content $home\c.txt
#From c.txt copy the files to destination
Get-Content $home\c.txt | foreach {copy-item $home\Devoluciones\*$_*.dat $Destination\$_\}
#Clean temp files
Remove-Item -ErrorAction Ignore $home\a.txt -Force
Remove-Item -ErrorAction Ignore $home\b.txt -Force
Remove-Item -ErrorAction Ignore $home\c.txt -Force
I would like to achieve the same result doing it "cleaner" than this, i want to learn how to manipulate the string in one line and if is it possible copy all with only one command.
Thanks, Nestor.
Here is a simple implementation that should be self explanatory. I'm sure somebody will add a more concise one line answer as well.
$Files = Get-Childitem -path "$home\Devoluciones\*" -include *.dat
foreach ($file in $files) {
$company = $file.Name.Substring(3,3)
copy-item $file.FullName (join-path (join-path $Destination $company) $file.Name)
}
EDIT: Fixed error in destination path
EDIT2: Get-ChildItem "The Include parameter is effective only when the command includes the Recurse parameter or the path leads to the contents of a directory, such as C:\Windows*, where the wildcard character is specified"
All PowerShell can be written as one awful line if you want it to be but here is something that is quite terse.
$path = "$home\Devoluciones\"
$destination = "C:\temp"
Get-ChildItem "$path\dto*.dat" | Copy-Item -Destination {[System.IO.Path]::Combine($destination,($_.Name).Substring(3,3),$_.Name)} -Force
What this will do here is exactly what you want. Take all the filtered files and for each one copy it to the folder that corresponds with the 3-6th letter code contained within. If the destination folder does not exist then we use -Force to make it. Helpful for new company codes. We use [System.IO.Path]::Combine to make the target file path which consists of the destination folder, company folder and current file in the pipe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With