根据另一个CSV文件中的项目从一个CSV中删除项目

时间:2012-03-16 20:56:14

标签: powershell

我有一个生成CSV文件的脚本。该脚本的目的是验证是否缺少某个文件。例如,假设我有以下文件:

1.jpg
2.jpg
3.jpg
4.jpg

1.gif
3.gif

2.txt
3.txt

一旦脚本运行,它将生成一个报告,以便我可以直观地看到缺少的文件。报告看起来像:

JPG Files   GIF Files   TXT Files
1.jpg       1.gif   
2.jpg                   2.txt
3.jpg       3.gif       3.txt

所以你可以看到,我缺少1.txt和2.gif。

这是我的问题所在......

我现在有一个SECOND CSV文件,其中包含必须保存在FIRST CSV中的文件列表。现在必须从我的FIRST CSV中删除任何不在SECOND CSV文件中的内容。例如:

我的第一张CSV包含:

1.jpg
2.jpg
3.jpg

1.gif
3.gif

2.txt
3.txt

SECOND CSV表示需要保留以下文件:

1.jpg
3.jpg

1.gif

2.txt

因此,任何未出现在SECOND CSV文件中的内容都需要从保留相同格式的FIRST CSV中删除,这意味着如果缺少1.jpg(它仍然列在SECOND CSV中但不是它存在于C:\ JPG文件夹中)它必须在FIRST CSV中显示一个空格。

我希望这是有道理的。如果您有任何问题或需要澄清,请询问我。

以下是我的脚本中生成FIRST CSV的代码部分:

# Get dirs
$dirJPG = "C:\JPG"
$dirGIF = "C:\GIF"
$dirTXT = "C:\TXT"
$files = @()
$files += Get-ChildItem -Path $dirBGR -Filter "*.jpg"
$files += Get-ChildItem -Path $dirMI -Filter "*.gif"
$files += Get-ChildItem -Path $dirW3F -Filter "*.txt"


# Write a datetime stamped CSV file
$datetime = Get-Date -Format "MM_dd_yyyy_hhmm"
$files | Sort-Object -Property { $_.Name } | Group-Object -Property { 
[System.IO.Path]::GetFileNameWithoutExtension($_.Name) } | % {
            New-Object psobject -Property @{
                            "JPG" Files" = $_.Group | ? { $_.Extension -eq ".jpg" } | % { $_.Name }
                            "GIF Files" = $_.Group | ? { $_.Extension -eq ".gif" } | % { $_.Name }
                            "TXT Files" = $_.Group | ? { $_.Extension -eq ".txt" } | % { $_.Name }
            } } | Export-Csv -Path "$datetime.csv" -NoTypeInformation

预先感谢您的协助! :d

3 个答案:

答案 0 :(得分:1)

可以使用数组,但使用哈希表可能更有效。您可以通过第一个CSV项检查iterate(foreach)并检查文件是否为CSV1而不是CSV2:

# Get the files by directory for each file type
function Get-FilesByType() {
    param ([hashtable]$filters)

    $result = @{}
    foreach ($filter in $filters.Keys) {
        $path = $filters[$filter]
        Get-ChildItem -Path $path -Filter $filter | % {
            $result.Add($_.Name, $_)
        }
    }
    return $result
}

# Assume CSV1 hashtable already exists and is loaded

# Get the hashtable of files for CSV2
$csv2 = Get-FilesByType @{"*.jpg"="C:\JPG"; "*.gif"="C:\GIF"; "*.txt"="C:\TXT" }

# Remove items from CSV1 that do not exist in CSV2
# NOTE: You cannot remove items from the hashtable while
# iterating through the collection, so use a copy of the
# keys to iterate.
$keys = @()
$keys += $csv1.Keys
$keys | % {
    if ( ! $csv2.ContainsKey($_) ) {
        Write-Host "Removing $_"
        $csv1.Remove($_)
    }
}

# Write a datetime stamped CSV file
$datetime = Get-Date -Format "MM_dd_yyyy_hhmm"
$csv1.Values | Sort-Object -Property { $_.Name } | Group-Object -Property {
    [System.IO.Path]::GetFileNameWithoutExtension($_.Name)
} | % {
    New-Object psobject -Property @{
        "JPG Files" = $_.Group | ? { $_.Extension -eq ".jpg" } | % { $_.Name }
        "GIF Files" = $_.Group | ? { $_.Extension -eq ".gif" } | % { $_.Name }
        "TXT Files" = $_.Group | ? { $_.Extension -eq ".txt" } | % { $_.Name }
    }
} | Export-Csv -Path "$datetime.csv" -NoTypeInformation

答案 1 :(得分:0)

不要使用数组 - 像Ryan说的那样使用Hashtable。如果要从中删除元素,则该数组不是一个好的选择。

答案 2 :(得分:0)

发现我的问题是什么......我正在调用需要删除的文件,然后删除它们。我只需要添加一个非条件:

$keys = @()
$keys += $currentFiles.Keys
$keys | % {
    if (! $filesToKeep.ContainsKey($_)) {
        Write-Host "Removing $_"
        $currentFiles.Remove($_)
    }
}