I want to create a function to move file to a folder depending on the type of the file "C:\Users\dgoud\Desktop\TP4\Telechargement" to specific folder
I want to have the equivalent of this for PowerShell:
for root, dirs, files in os.walk("C:\Users\dgoud\Desktop\TP4\Telechargement"):
My PowerShell function:
function DeplacerDansBonDossier {
param (
$extension
)
foreach ($file in $files) {
$extn = [IO.Path]::GetExtension($line)
if ($extn -eq ".txt" )
{
Move-Item -Path "C:\Users\dgoud\Desktop\TP4\Documents"
}
elseif ($extn -eq ".mp3" )
{
Move-Item -Path "C:\Users\dgoud\Desktop\TP4\Musique"
}
elseif ($extn -eq ".wav" )
{
Move-Item -Path "C:\Users\dgoud\Desktop\TP4\Musique"
elseif ($extn -eq ".mp4" )
{
Move-Item -Path "C:\Users\dgoud\Desktop\TP4\VidBo"
}
elseif ($extn -eq ".mkv" )
{
Move-Item -Path "C:\Users\dgoud\Desktop\TP4\VidBo"
}
}
}
}
I think this is what you are looking for. This function will only accept Files as input, note that I'm using Get-ChildItem -File
below. Another point to consider is that, if there is a File
with the same name on the Destination Folder Move-Item
will throw with the following error:
Move-Item: Cannot create a file when that file already exists.
You can use -Force
if you want to replace the existing files or add a new condition there if there is an existing file with the same name.
function DeplacerDansBonDossier {
[cmdletbinding()]
param(
[parameter(mandatory,valuefrompipeline)]
[System.IO.FileInfo]$File
)
begin
{
$Paths = @{
Documents = "C:\Users\dgoud\Desktop\TP4\Documents"
Music = "C:\Users\dgoud\Desktop\TP4\Musique"
Video = "C:\Users\dgoud\Desktop\TP4\VidBo"
}
}
process
{
switch -Regex($File.Extension)
{
'^\.txt$'{
$File | Move-Item -Destination $Paths['Documents']
Write-Verbose ('Moved {0} to {1}' -f $file.Name,$Paths['Documents'])
break
}
'^\.mp3$|^\.wav$'{
$File | Move-Item -Destination $Paths['Music']
Write-Verbose ('Moved {0} to {1}' -f $file.Name,$Paths['Music'])
break
}
'^\.mp4$|^\.mkv$'{
$File | Move-Item -Destination $Paths['Video']
Write-Verbose ('Moved {0} to {1}' -f $file.Name,$Paths['Video'])
break
}
}
}
}
How to use the function:
Get-ChildItem 'C:\Users\dgoud\Desktop\TP4\Telechargement' -File | DeplacerDansBonDossier
# If you want to see which Files are being moved and their destination
# you can use -Verbose
Get-ChildItem 'C:\Users\dgoud\Desktop\TP4\Telechargement' -File | DeplacerDansBonDossier -Verbose
It goes without saying that there are lots of ways to accomplish this. You may not need a function at all as these files could be piped directly to a ForEach-Object
loop. At any rate, if we are using a function I would start by sending the collection of [FileInfo]
objects generated by Get-ChildItem
to the function. This is in place of the extension.
That might look something like this:
Function DeplacerDansBonDossier {
param (
$Files
)
foreach ( $file in $files ) {
$extn = $File.Extension
if ($extn -eq ".txt" ) {
Move-Item -Path $File -Destination "C:\Users\dgoud\Desktop\TP4\Documents"
}
elseif ($extn -eq ".mp3" ) {
Move-Item -Path $File -Destination "C:\Users\dgoud\Desktop\TP4\Musique"
}
elseif ($extn -eq ".wav" ) {
Move-Item -Path $File -Destination "C:\Users\dgoud\Desktop\TP4\Musique"
}
elseif ($extn -eq ".mp4" ) {
Move-Item -Path $File -Destination "C:\Users\dgoud\Desktop\TP4\VidBo"
}
elseif ($extn -eq ".mkv" ) {
Move-Item -Path $File -Destination "C:\Users\dgoud\Desktop\TP4\VidBo"
}
}
} # End Function DeplacerDansBonDossier
In your demo code you had the extension, but you didn't have the file object on hand so effectively there was nothing to move.
Another variation using the switch statement as @AbrahamZinala suggested:
Function DeplacerDansBonDossier {
param (
$Files
)
foreach ($file in $files) {
$extn = $File.Extension
Switch ($extn)
{
'.txt' { Move-Item -Path $File -Destination "C:\Users\dgoud\Desktop\TP4\Documents"; Break }
'.mp3' { Move-Item -Path $File -Destination "C:\Users\dgoud\Desktop\TP4\Musique"; Break }
'.wav' { Move-Item -Path $File -Destination "C:\Users\dgoud\Desktop\TP4\Musique"; Break }
'.mp4' { Move-Item -Path $File -Destination "C:\Users\dgoud\Desktop\TP4\VidBo"; Break }
'.mkv' { Move-Item -Path $File -Destination "C:\Users\dgoud\Desktop\TP4\VidBo"; Break }
}
}
} # End Function DeplacerDansBonDossier
$Files = Get-ChildItem -Path C:\temp\SourceFolder
DeplacerDansBonDossier $Files
Obviously Switch
makes things more concise, but not as descriptive. Also, note the break
statements. Unlike If\ElseIf
a Switch
statement will evaluate more than 1 condition and script block. We stop that behavior with Break
Not to be redundant, but there's a lot more that could be done here. For example we could pipeline enable the function so it can be piped right after Get-ChildItem
, but it may not be worth it considering aforementioned potential of ForEach-Object
would operate much the same.
Example with ForEach-Object
:
Get-ChildItem -Path C:\temp\SourceFolder |
ForEach-Object{
foreach ( $file in $files ) {
$extn = $File.Extension
if ($extn -eq ".txt" ) {
Move-Item -Path $_ -Destination "C:\Users\dgoud\Desktop\TP4\Documents"
}
elseif ($extn -eq ".mp3" ) {
Move-Item -Path $_ -Destination "C:\Users\dgoud\Desktop\TP4\Musique"
}
elseif ($extn -eq ".wav" ) {
Move-Item -Path $_ -Destination "C:\Users\dgoud\Desktop\TP4\Musique"
}
elseif ($extn -eq ".mp4" ) {
Move-Item -Path $_ -Destination "C:\Users\dgoud\Desktop\TP4\VidBo"
}
elseif ($extn -eq ".mkv" ) {
Move-Item -Path $_ -Destination "C:\Users\dgoud\Desktop\TP4\VidBo"
}
}
}
Note: I wouldn't use Switch
in the ForEach-Object
script block. $_
operates differently in a Switch
context.
Note: None of this is tested. You may need to use the .FullName
property for the -Path
argument, either $File.FullName
or $_.FullName
. the *-Item
cmdlets can be fussy in that way.
Adding to the other great answers already, if the extensions always map to those paths, storing them in a hash table could be used here.
function DeplacerDansBonDossier {
[CmdletBinding()]
param (
[Parameter(Mandatory, ValueFromPipeline)]
[System.IO.FileInfo]
$File,
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string]
$Username = $env:USERNAME
)
begin {
$extensionDestinationMappings = @{
".txt" = "C:\Users\$Username\Desktop\TP4\Documents"
".mp3" = "C:\Users\$Username\Desktop\TP4\Musique"
".wav" = "C:\Users\$Username\Desktop\TP4\Musique"
".mp4" = "C:\Users\$Username\Desktop\TP4\VidBo"
".mkv" = "C:\Users\$Username\Desktop\TP4\VidBo"
}
}
process {
$extension = $File.Extension
# Check extension exists in hashtable beforehand
if ($extensionDestinationMappings.ContainsKey($extension)) {
Move-Item -Path $File.FullName -Destination $extensionDestinationMappings[$extension]
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.