我有一个生成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
答案 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($_)
}
}