[英]Powershell move all download to another folder function
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我想创建一个 function 将文件移动到一个文件夹,具体取决于文件“C:\Users\dgoud\Desktop\TP4\Telechargement”到特定文件夹的类型
I want to have the equivalent of this for PowerShell:我想为 PowerShell 提供等价物:
for root, dirs, files in os.walk("C:\Users\dgoud\Desktop\TP4\Telechargement"):
My PowerShell function:我的 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.这个 function 将只接受文件作为输入,请注意我在下面使用
Get-ChildItem -File
。 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
上有同名File
,则会抛出以下错误:
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.如果要替换现有文件,则可以使用
-Force
,如果存在同名的现有文件,则可以在其中添加新条件。
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: 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.您可能根本不需要 function,因为这些文件可以直接通过管道传输到
ForEach-Object
循环。 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.无论如何,如果我们使用 function,我会首先将
Get-ChildItem
生成的[FileInfo]
对象的集合发送到 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.在您的演示代码中,您有扩展名,但您手头没有 object 文件,因此实际上没有什么可移动的。
Another variation using the switch statement as @AbrahamZinala suggested: @AbrahamZinala 建议使用 switch 语句的另一个变体:
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.显然
Switch
使事情更简洁,但没有描述性。 Also, note the break
statements.另外,请注意
break
语句。 Unlike If\ElseIf
a Switch
statement will evaluate more than 1 condition and script block.与
If\ElseIf
不同, Switch
语句将评估多个条件和脚本块。 We stop that behavior with Break
我们用
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.例如,我们可以通过管道启用 function 以便它可以在
Get-ChildItem
之后立即进行管道传输,但考虑到上述ForEach-Object
的潜力将运行大致相同,这可能不值得。
Example with ForEach-Object
: 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.注意:我不会在
ForEach-Object
脚本块中使用Switch
。 $_
operates differently in a Switch
context. $_
在Switch
上下文中的操作方式不同。
Note: None of this is tested.注意:这些都没有经过测试。 You may need to use the
.FullName
property for the -Path
argument, either $File.FullName
or $_.FullName
.您可能需要为
-Path
参数使用.FullName
属性,即$File.FullName
或$_.FullName
。 the *-Item
cmdlets can be fussy in that way. *-Item
cmdlet 在这种情况下可能会很麻烦。
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.已经添加到其他很好的答案,如果扩展总是 map 到这些路径,则可以在此处使用将它们存储在 hash 表中。
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]
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.