【问题标题】:powershell script to merge .csv files by filename prefixpowershell 脚本通过文件名前缀合并 .csv 文件
【发布时间】:2021-01-19 20:43:10
【问题描述】:

我目前正在尝试比较和合并 .csv 文件,这些文件在 Powershell 中按各自的文件名命名为“xxx_yyy_zzz”。所有具有相同“xxx_yyy”模式的文件都应该合并到一个名为“xxx_yyy”的 .csv 文件中,最好合并到同一目录中。

我现在正在使用 for-loops 和 ArrayList(我尝试将对象分组以使用 -Split 或 -SkipLast,但在再次读取已经存在的合并文件时遇到了问题)。我得到了比较(大部分),但我似乎无法将 .csv 文件与导入/导出命令合并。

正在创建文件并且它们的名称是正确的,但它们始终是空的。我不确定我是否完全理解 Export-CSV 的正确用法以及如何将多个文件放入命令中...有什么帮助吗?

这是我的代码:

$array = @((Get-ChildItem -Path 'C:\Users\neich\Documents\ConvertXLSXToCSV\Testfolder' -Name )) #declare the array
$matchArrayList = New-Object System.Collections.ArrayList #declare ArrayList

#for-loop grabs each file, splits the filename (for comparisons) and adds the filename to an ArrayList
for ($i=0; $i -lt $array.length; $i++) { 
    $filearray = @((Get-ChildItem -Path 'C:\Users\neich\Documents\ConvertXLSXToCSV\Testfolder' -Name )) 
    $filenameArray = $filearray[$i].Split("_") 
    $match1 = $filearray[$i] 
    [void]$matchArrayList.Add($match1) #void suppresses the return of indices

        #second for-loop iterates over the files to compare them to fhe first one, if-statements ensure that only files "after" the first one are checked;
        #matches are added to the ArrayList
        for ($ii=$i; $ii -lt $array.length; $ii++) { 
            $filearray2 = @((Get-ChildItem -Path 'C:\Users\neich\Documents\ConvertXLSXToCSV\Testfolder' -Name ))
                if($i -lt $ii) { 
                    $filenameArray2 = $filearray2[$ii].Split("_") 
                        if($filenameArray[0] -eq $filenameArray2[0] -and $filenameArray[1] -eq $filenameArray2[1] -and !($filenameArray[2] -eq $filenameArray2[2])) {     # Check for matching prefixes and different endings     
                            $match2 = $filearray[$ii]           
                            [void]$matchArrayList.Add($match2) 
                }
        }
    } #end of $ii for-loop

    #for-loop is supposed to import all files from the ArrayList and merge them into a single .csv;
    #ArrayList is cleared at the end for the following iterations of the first for-loop
    if ($filenameArray[2]) { #prevents already merged files from being merged again (since they only have two indices)
       $mergedName = $filenameArray[0] + "_" + $filenameArray[1]
       $pathNameExport = "C:\Users\neich\Documents\ConvertXLSXToCSV\Testfolder\" + $mergedName + ".csv" 
         for ($iii = 0; $iii -lt $matchArrayList.Count; $iii++) {
            $pathNameImport = "C:\Users\neich\Documents\ConvertXLSXToCSV\Testfolder\" + $matchArrayList[$iii]
             IMPORT-CSV $pathName | Export-Csv -Path $pathNameExport -Delimiter "," -NoTypeInformation
             #insert code to delete matches(WIP)
         } #end of $iii for-loop
    }
$matchArrayList.Clear()
} #end of $i for-loop

【问题讨论】:

    标签: powershell csv


    【解决方案1】:

    我使用了原始数据 (get-content | selct-object -skip 2) 而不是导入 csv。然后我们使用一个 foreach 循环和一个数组来附加另一个文件,然后我们使用 set-content 导出这个完整的数组来覆盖文件。这是一个 hacky 修复,但它对我的工作时间比我尝试为它构建的任何其他脚本都少。

    【讨论】:

    • Np,有时候没想到会让你得到我所有脚本中最多的 #100%
    【解决方案2】:

    找到了解决办法。修改第一行的路径就可以了

    
    $path = "C:\Users\neich\Documents\ConvertXLSXToCSV\Testfolder" #set Path to .csv directory
    $array = @((Get-ChildItem -Path $path -Name )) #declare the array
    $matchArrayList = New-Object System.Collections.ArrayList #declare ArrayList
    
    #for-loop grabs each file, splits the filename (for comparisons) and adds the filename to an ArrayList
    for ($i=0; $i -lt $array.length; $i++) {
        $filearray = @((Get-ChildItem -Path $path -Name ))
    
      if ($filearray[$i]) {
        $filenameArray = $filearray[$i].Split("_") 
        $match1 = $filearray[$i] 
        [void]$matchArrayList.Add($match1) #void suppresses the return of indices
            #second for-loop iterates over the files to compare them to fhe first one, first if-statement ensures that only files "after" the first one are checked; 
            #last if-Statement compares the first two substrings and makes sure the third one mismatches (prevents already merged files to be merged again)
            #matches are added to the ArrayList
            for ($ii=$i; $ii -lt $array.length; $ii++) { 
                $filearray2 = @((Get-ChildItem -Path $path -Name ))
                    if($i -lt $ii) {
                        if ($filearray2[$ii]) {
                        $filenameArray2 = $filearray2[$ii].Split("_") 
                            if($filenameArray[0] -eq $filenameArray2[0] -and $filenameArray[1] -eq $filenameArray2[1] -and !($filenameArray[2] -eq $filenameArray2[2])) {     # Check for matching prefixes and different endings     
                                $match2 = $filearray[$ii]           
                                [void]$matchArrayList.Add($match2) 
                             }
                         }
                     }
             } #end of $ii for-loop
    
     
        #if-Statement prevents already merged files from being merged again (since they only have two indices)
        if ($filenameArray[2]) {
           $mergedName = $filenameArray[0] + "_" + $filenameArray[1]
           $pathNameExport = $path + "\" + $mergedName + ".csv" 
             
             #for-loop iterates over all matches, extracts the data and adds it to a new file. Matches are then deleted to prevent redundancy in further $i + $ii loops
             for ($iii = 0; $iii -lt $matchArrayList.Count; $iii++) {
                if ($matchArrayList[$iii]) {
                    $pathNameImport = $path + "\" + $matchArrayList[$iii]
                    $export = Get-Content -Path $pathNameImport
                    $export | Add-Content -Path $pathNameExport
                    cd $path                                                        #you need to navigate to the directory before removing the files; otherwise the directory itself will be deleted.
                    Remove-Item $matchArrayList[$iii] -ErrorAction SilentlyContinue     
                 }      
             } #end of $iii for-loop
        }$matchArrayList.Clear()
      }
    } #end of $i for-loop
    

    【讨论】:

      猜你喜欢
      • 2016-03-19
      • 2021-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      • 2018-11-10
      • 1970-01-01
      • 2021-12-15
      相关资源
      最近更新 更多