简体   繁体   English

Powershell 命令/脚本根据日期将文件移动到子目录(在文件名的前 8 个字符中)

[英]Powershell command / script to move files to subdirectories based on date (in the first 8 characters of the file name)

I have a bunch of files like these in a directory, many thousands of them.我在一个目录中有一堆这样的文件,成千上万个。

20210528_195406.jpg
20210528_195406.xmp
20210529_113416.mp4
20210529_113416.xmp
20210529_151444.jpg
20210529_151444.xmp
20210530_150950.mp4
20210530_150950.xmp
20210601_175932.txt
20210601_175932~2.mp4
20210601_175932~2.xmp

I am looking for an easy way (Powershell command) to copy the files to subdirectories based on year / month / day.我正在寻找一种简单的方法(Powershell 命令)来根据年/月/日将文件复制到子目录。

So for example, the file 20210601_175932.jpg would be moved to (a newly created) subdirectory: 2021\06\01\ .例如,文件20210601_175932.jpg将被移动到(新创建的)子目录: 2021\06\01\

How do I do this with Powershell?如何使用 Powershell 执行此操作? I know that Exiftool can do this by using: exiftool -v -ext jpg -ext mp4 "-Directory<CreateDate" -d %Y\%m\%d\.我知道 Exiftool 可以通过使用: exiftool -v -ext jpg -ext mp4 "-Directory<CreateDate" -d %Y\%m\%d\.

But this only works for image and video files.但这仅适用于图像和视频文件。

Any idea how to solve this for all file types?知道如何为所有文件类型解决这个问题吗?

Thanks.谢谢。

I believe something like this would suffice:我相信这样的事情就足够了:

$dataPath = "$PSScriptRoot/data"
$newDataPath = "$PSScriptRoot/structuredData"
Get-ChildItem $dataPath | ForEach-Object {
    $year = $_.BaseName.Substring(0, 4)
    $month = $_.BaseName.Substring(4, 2)
    $day = $_.BaseName.Substring(6, 2)

    $path = "$newDataPath\$year\$month\$day"
    if (-not (Test-Path $path)) {
        New-Item -ItemType Directory -Path $path
    }

    Move-Item -Path $_.FullName -Destination $path
}

I'm iterating all the files found in the directory, get the year, month and day from the file name then I check if the path exists.我正在迭代目录中找到的所有文件,从文件名中获取年、月和日,然后检查路径是否存在。 If it doesn't I create it.如果不是我创建它。 Then I move the file there.然后我把文件移到那里。

So, something like this?那么,像这样的事情?

$Folder_Location = "C:\brief\datefolder"

Get-ChildItem -Path $Folder_Location -File | 
    ForEach-Object -Process {
        
        #Assign current object in pipeline to something more readable
        $File = $_
        #$Folder_Name = [datetime]::ParseExact("$($File.Name.Split('_')[0])", "yyyymmdd", $null)
        #Split the name at the underscore keeping just the "date"
        $Folder_Name = $File.Name.Split('_')[0]
        
        #Assign the full destination path to a variable and test against it
        $Destination_Path = "C:\brief\datefolder\$Folder_Name"
        $Test_Destination = Test-Path -Path $Destination_Path
        
        #Evaluate against the returned bool value from $Test_Destination
        if ($Test_Destination -eq $False){

            #if folder doesn't exist, create it, and move the file in it
            New-Item -Path C:\brief\datefolder -Name $Folder_Name -ItemType Directory
            Move-Item -Path $File.FullName -Destination $Destination_Path

        }
        else { 

            #"Folder exists"
            #If folder already exists, just move the file.
            Move-Item -Path $File.FullName -Destination $Destination_Path

        }
    }

Given that you want to move them all into directories within the same one that you're pulling from.鉴于您想将它们全部移动到您从中提取的同一个目录中。

Edit: added some inline comments编辑:添加了一些内联注释

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM