【问题标题】:Powershell - Import-CSV then use specific column for exclusion arrayPowershell - Import-CSV 然后使用特定列作为排除数组
【发布时间】:2013-02-08 17:51:01
【问题描述】:

我在这个方面度过了一天。我正在尝试使用 powershell 导入一个 CSV 文件,该文件是 XML 的日志文件,稍后将在脚本中处理。

目标是在脚本顶部有一个 if 语句,以排除每个已经以这种方式处理的文件的 $_.FullName 如果脚本运行多次,它将读取此列而不处理文件第二次。

注意:我对 powershell 很陌生,抱歉语法草率

下面是我当前的代码和尝试

$sourceDir = "C:\test" #Production Folder "D:\Vodassets\_PreImport_Success"
$tempDir = "C:\test-temp"
$targetDir = "C:\test-copyback"
$Date = Get-Date -format MM-dd-yyyy
$Time =     "{0:h:mm:ss tt zzz}" -f (get-date)
$LogFile = "Disney-Log.csv"


### Copy Disney Metadata.xml's to a temporary folder for the editting process
if (Test-Path $LogFile){
    $ImportLog = Import-CSV $LogFile
    $GetXML = @(Get-ChildItem $sourceDir -recurse -filter "Metadata.xml" -exclude {$LogFile.Fullname} | Where-Object {$_.FullName -like "*disney*"})
} else {
    $GetXML = @(Get-ChildItem $sourceDir -recurse -filter "Metadata.xml" | Where-Object {$_.FullName -like "*disney*"})
}
$OutXML = ForEach-Object { $GetXML } | Select LastWriteTime,Fullname,DirectoryName
if ($GetXML.count -eq 0){
    write-host "No files to copy. Ending Process....." -foregroundcolor yellow -backgroundcolor black 
} else {
    ForEach ($File in $GetXML)
    {   $Path = $File.DirectoryName.Replace($sourceDir,$tempDir)
        if (-not (Test-Path $Path)) {
            Write-Host "Destination $Path doesn't exist, creating it." -foregroundcolor yellow -backgroundcolor black
            New-Item -Path $Path -ItemType Directory
            Copy-Item -Path $File.FullName -Destination $Path -ErrorAction silentlyContinue }
            elseif (-not $?) { write-warning "Failed to copy $($File.Fullname)" }
            else { write-host "Succesfully copied $($File.Fullname) to $($tempDir)" -foregroundcolor green -backgroundcolor black }
        }



### Edit XML Process
    ForEach ($File in $GetXML)
    {   $Path = $File.DirectoryName.Replace($sourceDir,$tempDir)
        if (Test-Path $Path) {
            $xmlData = [xml](Get-Content $File.FullName)
            foreach ($group in $xmlData){
                $xmlData.assetpackages.assetpackage.'Type' = 'SVOD'
                $xmlData.assetpackages.assetpackage.'Product' = 'SVOD'
                $xmlData.assetpackages.assetpackage.'Name' = 'Disney Family Movies'
            }
        }
        $xmlData.Save($File.Fullname)   
    }


    $OutXML | Export-Csv $LogFile -NoTypeInformation -Force -Append


### Copy Files to VOD Import Server
    $import = (Get-ChildItem $tempDir -recurse -filter "Metadata.xml" | Where-Object {$_.FullName -like "*disney*"})
    if ($import.count -eq 0) {
        write-host "No files to import. Ending Process....." -foregroundcolor yellow -backgroundcolor black
    } else {
        ForEach ($File in $import)
        {   $Path = $File.DirectoryName.Replace($tempDir,$targetDir)
            if (-not (Test-Path $Path)) {
                Write-Host "Destination $Path doesn't exist, creating it." -foregroundcolor yellow -backgroundcolor black
                New-Item -Path $Path -ItemType Directory
                Copy-Item -Path $File.FullName -Destination $Path -ErrorAction silentlyContinue }
                elseif (-not $?) { write-warning "Failed to copy $($File.Fullname)" }
                else { write-host "Succesfully copied $($File.Fullname) to $($targetDir)" -foregroundcolor green -backgroundcolor black }
            }
    }


### Cleanup temporary directory
    if (-not (Test-Path $tempDir | Where-Object {$_.FullName -like "*disney*"})){
        Get-ChildItem $tempDir -recurse | % { Remove-Item $_.FullName -recurse } #Remove the -whatif to actual clean out the directory
    }
}

【问题讨论】:

    标签: windows powershell csv import


    【解决方案1】:

    我在您的文件中看到了多个需要注意的地方:

    • $OutXML = ForEach-Object { $GetXML } | Select LastWriteTime,Fullname,DirectoryName #Foreach loop is unnecessary. $OutXML = $GetXML | Select ... works

    • New-Item -Path $Path -ItemType Directory #ItemType should be File

    • 您的 XML 编辑看起来有问题。您要求每个group,但每次您尝试编辑整个文件xmlData

    可能还有更多,这些只是早期引起我注意的那些。

    要回答您的问题,请查看下面的代码。它应该给出如何解决它的想法。如果文件路径是您存储在日志中的唯一内容,则应该使用纯文本文件,因为它更快更容易。我在下面包含了文本文件和 csv 的解决方案。由于您没有提供 csv-headers/sample,所以解决方案是针对单列 csv(我不知道您想如何将其保存回 csv)。

    #Load from csv
    $log = Import-Csv .\test.csv
    $loggedpaths = $log | Select-Object -ExpandProperty FullName
    
    #Get only untouched files
    $GetXML = @(Get-ChildItem $sourceDir -recurse -filter "Metadata.xml" | Where-Object {$_.FullName -like "*disney*" -and $loggedpaths -notcontains $_.FullName})
    
    #Add processed file after editing(after $xmldata.save($file.fullname)
    $log += $file | Select-Object LastWriteTime, Fullname, DirectoryName
    
    #Save log to csv
    $log | Export-Csv .\test.csv -NoTypeInformation
    

    【讨论】:

    • @Grainer,感谢您的所有建议。我正在导出以 CSV 格式处理的文件,其中包含 $OutXML = ForEach-Object { $GetXML } | 行。选择 LastWriteTime、Fullname、DirectoryName 和 $OutXML | Export-Csv $LogFile -NoTypeInformation -Force -Append 所以 CSV 有 3 列 LastWriteTime,Fullname,DirectoryName 我使用 LastWriteTime 作为文件处理时间的时间戳,因为它使用的是从复制到临时目录时的时间戳,所以它是相当准确我已经测试过了。我需要时间戳以便以后在另一个 powershell 脚本中使用。
    • 另外,在测试您对导入日志文件的建议之一时,$ImportLog = Import-CSV $LogFile |选择 -ExpandProperty FullName $GetXML = @(Get-ChildItem $sourceDir -recurse -filter "Metadata.xml" | Where-Object {$_.FullName -like "disney" -and $LogFile -notcontains $_.FullName}) 调用 $ImportLog 显示已处理的文件,但 -and $LogFile -notcontains $_.FullName} 似乎无法排除 $LogFile 输出的任何内容
    • 我使用 $GetXML = @(Get-ChildItem $sourceDir -recurse -filter "Metadata.xml" | Where-Object {$_.FullName -like "disney" -and $ImportLog -notcontains $_.FullName}) 关键是 $ImportLog 而不是 $LogFile
    • 好。 Ofc 您需要更改名称。如前所述,我的答案并不完整。这只是对您有帮助的部分。
    • 我最后一次更新了答案,以更好地满足您的需求。 (加载和保存日志)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    • 2014-09-27
    • 2020-02-27
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 2019-06-14
    相关资源
    最近更新 更多