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
我有两个关于使用 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