根据CSV

时间:2017-12-13 21:53:08

标签: powershell

根据两个项目中的公共值,寻找有关如何将文件与文件夹匹配的一些指导。 我有一个.csv文件,格式如下:

Files                   Paths
-----                   -----
file_JPG_1.zip          C:\path\to\JPG
file_GIF_1.zip          C:\path\to\GIF
file_PNG_1.zip          C:\path\to\JPG
file_PNG_2.zip          C:\path\to\GIF
file_PNG_3.zip          C:\path\to\JPG
file_BMP_2.zip          C:\path\to\GIF
file_JPG_3.zip
file_GIF_3.zip
file_PNG_4.zip
file_PNG_5.zip
file_PNG_6.zip
file_BMP_3.zip

我有一个完整的'文件'列表,但没有完整的'路径'列表。

我要做的是根据文件名和文件夹路径中存在的文件类型,在.csv的“路径”列中。 所以基本上,任何包含'JPG'的文件名都会有相应的路径,其中包含粘贴在'Paths'列中的'JPG'。

我正在寻找的最终结果应该是:

Files                   Paths
-----                   -----
file_JPG_1.zip          C:\path\to\JPG
file_GIF_1.zip          C:\path\to\GIF
file_PNG_1.zip          C:\path\to\PNG
file_PNG_2.zip          C:\path\to\PNG
file_PNG_3.zip          C:\path\to\PNG
file_BMP_2.zip          C:\path\to\BMP
file_JPG_3.zip          C:\path\to\JPG
file_GIF_3.zip          C:\path\to\GIF
file_PNG_4.zip          C:\path\to\PNG
file_PNG_5.zip          C:\path\to\PNG
file_PNG_6.zip          C:\path\to\PNG
file_BMP_3.zip          C:\path\to\BMP

文件将按(大致)按上面显示的顺序排序。 我可以自己从这两个列中获取值,但我似乎无法弄清楚如何实现这一点。

关于如何实现这一目标的任何提示/想法/建议? 谢谢!!

** 更新:请参阅下面的说明 **

好的,我会尽我所能澄清我的问题。

我通过电子邮件获取了需要提取的文件列表和目的地。 我正在对这封电子邮件做的是取出所有文本,只保留文件名+文件需要提取到的目标路径,并将其存储在将由另一个脚本处理的.CSV文件中。 邮件的格式如下:

1. Extract 3452_JPG_FDR_435_DRF1712 - JPG.ZIP to C:\Images\Graphics\JPG\fdr_435
2. Extract 3452_GIF_FDR_435_DRF1712 - GIF.ZIP to C:\Images\Graphics\GIF\fdr_435
3. Extract 3452_PNG_FDR_435_DRF1712 - PNG.ZIP to C:\Images\Graphics\PNG\fdr_435
etc...

使用上面的例子,我能够正确生成.CSV文件,所以我最终会得到:

Files                                Paths
-----                                -----
3452_JPG_FDR_435_DRF1712 - JPG.ZIP   C:\Images\Graphics\JPG\fdr_435
3452_GIF_FDR_435_DRF1712 - GIF.ZIP   C:\Images\Graphics\GIF\fdr_435
3452_PNG_FDR_435_DRF1712 - PNG.ZIP   C:\Images\Graphics\PNG\fdr_435
etc...

问题出现时,电子邮件中会列出.Z0x(这些是WinRar SFX文件),因为电子邮件会显示:

1. Extract 3452_JPG_FDR_435_DRF1712 - JPG.ZIP to C:\Images\Graphics\JPG\fdr_435
-The following will be automatically extracted:
3452_JPG_FDR_435_DRF1712 - JPG.Z01
3452_JPG_FDR_435_DRF1712 - JPG.Z02
etc...

我剩下的是.CSV现在看起来像这样:

Files                                                        Paths
-----                                                        -----
3452_JPG_FDR_435_DRF1712 - JPG.ZIP                           C:\Images\Graphics\JPG\fdr_435
3452_JPG_FDR_435_DRF1712 - JPG.Z01                           C:\Images\Graphics\PNG\fdr_435
3452_PNG_FDR_435_DRF1712 - PNG.ZIP                           C:\Images\Graphics\BMP\fdr_435
3452_PNG_FDR_435_DRF1712 - PNG.Z01                           C:\Images\Graphics\GIF\fdr_435
3452_PNG_FDR_435_DRF1712 - PNG.Z02                           C:\Images\Graphics\RAW\FDR
3452_BMP_FDR_435_DRF1712 - BMP.ZIP                           C:\Images\Graphics\ICO\fdr_435
3452_BMP_FDR_435_DRF1712 - BMP.Z01                           C:\Images\Graphics\ICO\fdr_120
3452_BMP_FDR_435_DRF1712 - BMP.Z02                           C:\Images\Graphics\ICO\fdr_120
3452_BMP_FDR_435_DRF1712 - BMP.Z03                             
3452_GIF_FDR_435_DRF1712 - GIF.ZIP                   
3463_RAW_FDR_DRF1712 - RAW.ZIP                               
3457_ICO_fdr_435_STC1712 - ICO.ZIP                     
3456_ICO_FDR_435_DRF1712_ICO VO - ICO.ZIP          
3456_ICO_FDR_435_DRF1712_ICO VO - ICO_SET 2.ZIP

正如您所看到的,文件的路径不再排列。 我的想法是,我想用路径列填充.Z0x文件将被提取到的路径列。 所以最终结果应该是.CSV,看起来像:

Files                                                        Paths
-----                                                        -----
3452_JPG_FDR_435_DRF1712 - JPG.ZIP                           C:\Images\Graphics\JPG\fdr_435
3452_JPG_FDR_435_DRF1712 - JPG.Z01                           C:\Images\Graphics\JPG\fdr_435
3452_PNG_FDR_435_DRF1712 - PNG.ZIP                           C:\Images\Graphics\PNG\fdr_435
3452_PNG_FDR_435_DRF1712 - PNG.Z01                           C:\Images\Graphics\PNG\fdr_435
3452_PNG_FDR_435_DRF1712 - PNG.Z02                           C:\Images\Graphics\PNG\fdr_435
3452_BMP_FDR_435_DRF1712 - BMP.ZIP                           C:\Images\Graphics\BMP\fdr_435
3452_BMP_FDR_435_DRF1712 - BMP.Z01                           C:\Images\Graphics\BMP\fdr_435
3452_BMP_FDR_435_DRF1712 - BMP.Z02                           C:\Images\Graphics\BMP\fdr_435
3452_BMP_FDR_435_DRF1712 - BMP.Z03                           C:\Images\Graphics\BMP\fdr_435
3452_GIF_FDR_435_DRF1712 - GIF.ZIP                           C:\Images\Graphics\GIF\fdr_435
3463_RAW_FDR_DRF1712 - RAW.ZIP                               C:\Images\Graphics\RAW\FDR
3457_ICO_fdr_435_STC1712 - ICO.ZIP                           C:\Images\Graphics\ICO\fdr_435
3456_ICO_FDR_435_DRF1712_ICO VO - ICO.ZIP                    C:\Images\Graphics\ICO\fdr_120
3456_ICO_FDR_435_DRF1712_ICO VO - ICO_SET 2.ZIP              C:\Images\Graphics\ICO\fdr_120

使用提供的代码,我最终得到的Paths列如下所示:

Paths
-----
C:\Images\Graphics\JPG
C:\Images\Graphics\JPG
C:\Images\Graphics\PNG
C:\Images\Graphics\PNG
C:\Images\Graphics\PNG
C:\Images\Graphics\BMP
C:\Images\Graphics\BMP
C:\Images\Graphics\BMP
C:\Images\Graphics\BMP
C:\Images\Graphics\GIF
C:\Images\Graphics\RAW
C:\Images\Graphics\ICO
C:\Images\Graphics\ICO
C:\Images\Graphics\ICO

如果仍不清楚,请告诉我。

1 个答案:

答案 0 :(得分:3)

如果每个文件的文件夹都位于同一个地方,并且您的文件名都是这样的格式,就像在您的示例中一样,这非常简单。此答案使用.Split()方法和计算属性。

$CSVData = Import-Csv data.csv | Select Files,@{l='Paths';e={'C:\Path\To\' + $_.Files.Split('_')[1]}}

如果事情不像你的例子那么简单我们可以使用它,我们只需要一个更准确的例子和解释。

编辑:好的,查看更新后的CSV文件,我看到您在一列中列出了潜在路径,在另一列中列出了文件列表。我建议将路径列表转换为另一个变量。然后构建一个以这些路径为键的哈希表,并在反斜杠和下划线上分割路径(下划线,因为文件是下划线分隔的)。现在循环遍历文件,并在下划线上分割每个文件。将其与拆分路径进行比较,并选择匹配最多的路径。

以下是执行该操作的脚本:

#Import the CSV
$CSV = Import-Csv $CSVPath
#Capture all the unique paths
$AllPaths = $CSV.Paths | Select -Unique
#Make an empty hashtable
$AllPathsSplit = @{}
#Loop through paths, and add each to the hashtable as a key, with the path split on '\' and '_' as the value
$AllPaths |%{$AllPathsSplit.Add($_,($_ -split '\\|_'))}

#Loop through files
ForEach($File in $CSV){
    #Set the path by looking at each item in the hashtable and finding the one with the most matches to the file split on underscores
    $File.Paths = $AllPaths|Sort {(Compare-Object ($File.Files -split '_') -DifferenceObject $AllPathsSplit[$_] -ExcludeDifferent -IncludeEqual -PassThru).Count} -Descending |Select -First 1
}

这是输出:

PS C:\Users\TMTech> $CSV

Files                                           Paths                         
-----                                           -----                         
3452_JPG_FDR_435_DRF1712 - JPG.ZIP              C:\Images\Graphics\JPG\fdr_435
3452_JPG_FDR_435_DRF1712 - JPG.Z01              C:\Images\Graphics\JPG\fdr_435
3452_PNG_FDR_435_DRF1712 - PNG.ZIP              C:\Images\Graphics\PNG\fdr_435
3452_PNG_FDR_435_DRF1712 - PNG.Z01              C:\Images\Graphics\PNG\fdr_435
3452_PNG_FDR_435_DRF1712 - PNG.Z02              C:\Images\Graphics\PNG\fdr_435
3452_BMP_FDR_435_DRF1712 - BMP.ZIP              C:\Images\Graphics\BMP\fdr_435
3452_BMP_FDR_435_DRF1712 - BMP.Z01              C:\Images\Graphics\BMP\fdr_435
3452_BMP_FDR_435_DRF1712 - BMP.Z02              C:\Images\Graphics\BMP\fdr_435
3452_BMP_FDR_435_DRF1712 - BMP.Z03              C:\Images\Graphics\BMP\fdr_435
3452_GIF_FDR_435_DRF1712 - GIF.ZIP              C:\Images\Graphics\GIF\fdr_435
3463_RAW_FDR_DRF1712 - RAW.ZIP                  C:\Images\Graphics\RAW\FDR    
3457_ICO_fdr_435_STC1712 - ICO.ZIP              C:\Images\Graphics\ICO\fdr_435
3456_ICO_FDR_435_DRF1712_ICO VO - ICO.ZIP       C:\Images\Graphics\ICO\fdr_435
3456_ICO_FDR_435_DRF1712_ICO VO - ICO_SET 2.ZIP C:\Images\Graphics\ICO\fdr_435

我假设您所需的输出在最后两项中有错,因为文件名中没有任何内容表明该路径应为ICO \ fdr_120