Select 并使用 Powershell 从 CSV 导出最小值

Select and export minimum value from CSV using Powershell

我有两个关于使用 powershell 从 CSV 文件导出信息的问题。我真的没有太多经验 coding/using powershell,我一直在网上一起破解代码 tutorials/forums 等等

我有一个包含 CSV 文件的文件夹,其中有很多列。我正在编写的第一段代码是从每个以“_HIPOTS.csv”结尾的文件中提取包含 "CSEP DDS Matched" 或 "CSEP Unmatched" 的每一行,并将其导出到一个新文件中。我的代码是:

$path = "S:\TEST AREA\ac00418\OpsPlan\Test\Output\FY1\*.*"; # Directory containing csv files 

$csvFiles = Get-ChildItem -Path $path -Filter *_HIPOTS.csv; # Get the csv files
$destination = "S:\TEST AREA\ac00418\OpsPlan\Test\Output\FY1_CSEP_HighPotentials.csv"

#$content = $null
$content = @()

ForEach($csv in $csvFiles){
#IMPORT
        $nodes = import-csv $csv.Fullname
        $CSEPs = $nodes|where {$_.NodeSymbolName -match "CSEP DDS Matched" -and $_.NodeSymbolName -match "CSEP Unmatched"}
        $allCSEPs += $CSEPs
}

$allCSEPs|Export-csv $destination -NoTypeInformation

问题是,当我 运行 这个时,它没有搜索 "CSEP Unmatched" 而且它似乎 运行 通过 for 循环两次或三次,因为似乎有出口中有很多重复项。有人可以帮忙吗?

第二个问题是我必须从每个文件的另一列中导出包含最低值的行。我有一个与第一个类似的代码,除了我不知道如何从列中选择最小值:

$path = "S:\TEST AREA\ac00418\OpsPlan\Test\Output\FY1\*.*"; # Directory containing csv files 
$csvFiles = Get-ChildItem -Path $path -Filter *_HIPOTS.csv; # Get the csv files
$destination = "S:\TEST AREA\ac00418\OpsPlan\Test\Output\LowestNodePressure.csv"

#$content = $null
$content = @()



ForEach($csv in $csvFiles){
#IMPORT
        $nodes = import-csv $csv.Fullname
        $min = Measure-Object -Property $_.NodePressure -Minimum

        $minpressure += $min
}

$minpressure|Export-csv $destination -NoTypeInformation

这是信息显示方式的示例。请记住,有数以千计的这些和更多的专栏。这些只是我要编写的代码的相关代码。

NAME              NodeSymbolName    NodePressure    NodeResultFlow
6430050001023     CSEP Unmatched        24                -25
60200100000007    CSEP DDS Matched      49                -106
60200100000072    CSEP DDS Matched      25                -157
60200100000148    CSEP DDS Matched      35                -9

我为巨大的post道歉,但我想我还不如一箭双雕!希望我已经足够清楚我想要达到的目标。我感谢任何人可以提供的帮助。

谢谢,

J

好的,让我们将其总结为一个答案,而不仅仅是评论。这里有一些问题,所以让我们从头开始:

没有同时收集 'CSEP DDS Matched' 和 'CSEP Unmatched'

好的,没问题。如评论中所述,您想使用 -or 运算符,而不是 -and 运算符。更正的行:

        $CSEPs = $nodes|where {$_.NodeSymbolName -match "CSEP DDS Matched" -or $_.NodeSymbolName -match "CSEP Unmatched"}

更好的是,-match 运算符处理正则表达式(通常称为 RegEx),因此我们可以将整个事情缩短为:

        $CSEPs = $nodes|where {$_.NodeSymbolName -match "CSEP (DDS |un)Matched"}

RegEx 查看括号内的内容,并使用竖线作为分隔符来匹配其中的任何选项,因此这两种情况都适用。整洁吧?继续前进!

重复

是的,没有人喜欢这些,但我敢打赌这是重新使用您的会话和使用脏变量的问题。解决这个问题的最好方法是删除脚本末尾的变量。在调试时,如果需要,只需注释掉这些行,然后在准备好时取消注释。

Remove-Variable allCSEPs, nodes, CSEPs, LowestNode

每个文件的最低 NodePressure

好的,因为您希望每个文件都有它,所以您应该首先在浏览文件时收集这些文件,所以让我们在初始循环中添加一行。没有理由多次导入这些 CSV,对吗?我们将从第一个循环中查看您的匹配项,对它们进行排序,然后 select 第一个,并将该记录添加到不同的变量以单独输出。

[array]$LowestNodes += $CSEPs | Sort NodePressure | Select -First 1

看到我在那里做了什么吗?我将 $LowestNode 声明为一个数组,因此我可以使用 += 收集对象或字符串或其他任何内容的集合,而不必先将其声明为空数组。

这样你就有了 1 个循环(用来控制所有循环),它可能看起来像这样:

$path = "S:\TEST AREA\ac00418\OpsPlan\Test\Output\FY1\*.*"; # Directory containing csv files 

$csvFiles = Get-ChildItem -Path $path -Filter *_HIPOTS.csv; # Get the csv files
$destination = "S:\TEST AREA\ac00418\OpsPlan\Test\Output\FY1_CSEP_HighPotentials.csv"
$destination2 = "S:\TEST AREA\ac00418\OpsPlan\Test\Output\LowestNodePressure.csv"

ForEach($csv in $csvFiles){
#IMPORT
        $nodes = import-csv $csv.Fullname
        $CSEPs = $nodes|where {$_.NodeSymbolName -match "CSEP (DDS |un)Matched"}
        [array]$LowestNodes += $CSEPs | Sort NodePressure | Select -First 1
        [array]$allCSEPs += $CSEPs
}

$allCSEPs|Export-csv $destination -NoTypeInformation
$LowestNodes|Export-csv $destination2 -NoTypeInformation
Remove-Variable allCSEPs, nodes, CSEPs, LowestNodes