【问题标题】:Powershell loop is only running once file per filename, even if the filename exists with multiple extensionsPowershell循环每个文件名只运行一次文件,即使文件名存在多个扩展名
【发布时间】:2020-09-10 21:15:28
【问题描述】:

我将是第一个承认 PowerShell 不是我的强项的人,但在互联网上搜索了一晚上之后,我拼凑了以下内容。最终目标是通过 DateTaken 组织大量图像驱动器,以及 Sidecar XMP 文件(如果存在)。它可能不是最优雅的代码,但它几乎可以工作。

最后一个我想不通的问题是,foreach 循环只对每个文件名执行一次,而不管扩展名如何。例如,只会处理 DSC00001.arw、DSC00001.xmp、 DSC00001.jpg。

我们将不胜感激。

谢谢!

$Folders = (Get-ChildItem -Path F:\ -Recurse -Directory -Force).FullName

$objShell  = New-Object -ComObject Shell.Application
$Folders | % {

    $objFolder = $objShell.namespace($_)
    foreach ($File in $objFolder.items()) { 
            if (($File | Split-Path -Extension) -in ".arw",".gif",".tiff",".jpg",".png",".nef") {
                Write-Host $File.Name`t -NoNewline -ForegroundColor Green
                try {
                    $DateTaken = ($objFolder.getDetailsOf($File,12) -replace [char]8206)  -replace [char]8207
                    $DateTaken = [DateTime]::ParseExact($DateTaken, "g", $null)
                    $Year = $DateTaken.ToString('yyyy')
                    $Date = $DateTaken.ToString('yyyy-MM-dd')
                    Write-Host $Date`t -ForegroundColor Blue -NoNewline
                }
                catch {
                    $Year = 'Other'
                    $Date = 'Other'
                    Write-Host $Date`t -ForegroundColor DarkRed -NoNewline
                }
                finally {
                    $DatePath = (Join-Path (Join-Path F:\ $Year ) $Date)
                }
                write-Host $File.Path -> (Join-Path $DatePath ($File | Split-Path -Leaf))-NoNewline
                #Move-Item $File.Path (Join-Path $DatePath ($File | Split-Path -Leaf))
                Write-Host Completed`n -NoNewline

                if (Test-Path (Join-Path ($File | Split-Path) (($File | Split-Path -LeafBase) + '.xmp'))) {
                    Write-Host XMP:`t -ForegroundColor Magenta -NoNewLine
                    Write-Host (Join-Path ($File | Split-Path) (($File | Split-Path -LeafBase) + '.xmp')) -> (Join-Path ($DatePath) (($File | Split-Path -LeafBase) + '.xmp'))
                    #Move-Item (Join-Path ($File | Split-Path) (($File | Split-Path -LeafBase) + '.xmp')) (Join-Path ($DatePath) (($File | Split-Path -LeafBase) + '.xmp'))
                }
            }else {
                Write-Host $File.Name is not an image `n -NoNewline -ForegroundColor DarkYellow    
            }
    }

}

【问题讨论】:

  • 你确认$objShell.namespace("C:\folder\with\multiple\file\extensions").items()实际上返回了所有预期的项目吗?
  • 你正在做大量的拆分和连接......并且经常重复它们。尝试所有每个项目一次,看看你是否能看到错误在哪里。 ///// 我的第一个怀疑是你在那个过于复杂的分割和连接集中的某个地方修改你的文件。 [咧嘴]
  • @MathiasR.Jessen 是在正确的轨道上。 $objShell.Folder.items() 首先不会返回这些项目。我使用相同的循环,发现无论名称与不同的扩展名使用多少次,都只返回一个文件。

标签: powershell foreach organization powershell-7.0


【解决方案1】:

我不确定为什么 $objFolder.items() 实际上并没有返回所有预期的文件,但我建议使用 PowerShell 的内置文件系统提供程序来发现每个文件夹中的实际文件,然后使用 $objFolder.ParseName() 获取参考你可以传递给GetDetailsOf()

$Folders = (Get-ChildItem -Path F:\ -Recurse -Directory -Force).FullName

$objShell  = New-Object -ComObject Shell.Application
$Folders | % {

    $objFolder = $objShell.NameSpace($_)

    foreach ($FileInfo in Get-ChildItem -LiteralPath $_ -File -Force) { # <-- trick is right here, use Get-ChildItem to discover the files in the folder
        if($FileInfo.Extension -in ".arw",".gif",".tiff",".jpg",".png",".nef"){
            $File = $objFolder.ParseName($FileInfo.Name)                # <-- here we resolve the corresponding file item with shell app
    
            # ... resolve and parse dateTaken here, just like before

            # *.xmp file path might be easier to construct like this
            $xmpPath = $FileInfo.FullName -replace "$($FileInfo.Extension)`$",'.xmp'
            if(Test-Path -LiteralPath $xmpPath){
                 # ...
            }
        }
    }
}

【讨论】:

  • 这非常有效。有趣的是,我最初使用第二个 Get-ChildItem 编写代码,但不知道如何将其传递给 GetDetailsOf()
猜你喜欢
  • 1970-01-01
  • 2012-08-28
  • 1970-01-01
  • 1970-01-01
  • 2012-09-08
  • 1970-01-01
  • 2012-04-05
  • 1970-01-01
  • 2013-04-12
相关资源
最近更新 更多