わかりました、元のスクリプトは恐ろしく非効率的で、設計も不適切でした。これは、必要なことを行うためのpowershellです。一時ファイルは必要ありません。通常、私はこれほど多くのコメントを寄せることはありませんが、私が行ったことをすべての人に理解してもらいたいと思っています。出力ファイルは、このメソッドを実行した作業ディレクトリにあります。
使用法 (cmd/batch で): powershell -command "& { . \FileContainsThisFunction.ps1; Extract-Hosts original.csv }"
使用法 (powershell で): . \FileContainsThisFunction.ps1; Extract-Hosts original.csv
function Extract-Hosts {
param(
[Parameter(Mandatory=$true)]
[String]$InputFile
)
if(-not (Test-Path $InputFile)) { throw ("Input file doesn't exist: {0}" -f $InputFile) }
# Extract filename without path or extension
$BaseName = Get-Item $InputFile | Select -ExpandProperty Basename
# Create a custom object that conains the outfilename and the content for lwks and wks
$OutLwks = @{ File = ('{0}-lwks.csv' -f $Basename); Content = @() }
$OutWks = @{ File = ('{0}-wks.csv' -f $Basename); Content = @() }
# First, delete the output files if they exist
$OutLwks, $OutWks | ForEach { if (Test-Path -Path:($_.File)) { Remove-Item $_.File } }
# Import the original csv into the pipeline
Import-Csv $InputFile |
# We only care about the IP and Hostname columns
Select -Property IP, Hostname |
# Where the hostname is not empty, nor contains n/a or n/s
Where { $_.Hostname -iNotMatch '(^$|n/a|n/s)' } |
ForEach-Object {
# If it contains lwks, add it to that list
if ($_ -imatch 'lwks') {
($OutLwks.Content += $_)
}
# if it contains wks but NOT lwks, add to the other list
elseif ($_ -imatch 'wks') {
($OutWks.Content += $_)
}
} | Out-Null # Sends objects to null after pipeline processing.
# Splat each one into the appropriate CSV file
$OutLwks, $OutWks | ForEach-Object {
$_.Content | Export-Csv -Path $_.File -NoTypeInformation }
}
編集: 2 番目の Content 追加のタイプミスを修正しました。それは OutWks.Content += $_ と読むべきでした。編集 +: 理解しやすくするために Where マジックを Foreach に置き換えました。パイプライン後の出力を抑制する Out-Null を追加しました。
このスクリプトによって、PowerShell でリッチ パイプライン プロセッサを作成できるようになることを願っています。