如何通过函数arg传递csv列对象

时间:2015-12-21 15:01:22

标签: powershell powershell-v3.0

我想要清理很多重复的代码。我知道以下语法不正确,但你能告诉我正确的方法吗?假设我有以下代码......

Function GetColumnOneValues
{
    Param ($csvFile, $ValuesWithoutNullFile)

    Import-Csv $csvFile | Where-Object {$_.test1ColumnOne} | 
    Export-Csv $ValuesWithoutNullFile -NoTypeInformation -Force
}

Function GetColumnTwoValues
{
    Param ($csvFile, $ValuesWithoutNullFile)

    Import-Csv $csvFile | Where-Object {$_.test2ColumnTwo} | 
    Export-Csv $ValuesWithoutNullFile -NoTypeInformation -Force
}

Function GetColumnThreeValues
{
    Param ($csvFile, $ValuesWithoutNullFile)

    Import-Csv $csvFile | Where-Object {$_.test3ColumnThree} | 
    Export-Csv $ValuesWithoutNullFile -NoTypeInformation -Force
}

^注意重复的代码

Function Main
{
    $test1CsvFile = "C:\Scripts\Tests\test1.csv"
    $test1CsvFileResults = "C:\Scripts\Tests\test1Results.csv"
    $test2CsvFile = "C:\Scripts\Tests\test2.csv"
    $test2CsvFileResults = "C:\Scripts\Tests\test2Results.csv"
    $test3CsvFile = "C:\Scripts\Tests\test3.csv"
    $test3CsvFileResults = "C:\Scripts\Tests\test3Results.csv"

    GetColumnOneValues $test1CsvFile $test1CsvFileResults
    GetColumnTwoValues $test2CsvFile $test2CsvFileResults
    GetColumnThreeValues $test3CsvFile $test3CsvFileResults
}

Main

相反,它应该是这样的......

Function GetColumnValues
{
    Param ($csvFile, $ValuesWithoutNullFile, $ColumnName)

    Import-Csv $csvFile | Where-Object {$ColumnName} | 
    Export-Csv $ValuesWithoutNullFile -NoTypeInformation -Force
}

Function Main
{
    $test1CsvFile = "C:\Scripts\Tests\test1.csv"
    $test1CsvFileResults = "C:\Scripts\Tests\test1Results.csv"
    $test2CsvFile = "C:\Scripts\Tests\test2.csv"
    $test2CsvFileResults = "C:\Scripts\Tests\test2Results.csv"
    $test3CsvFile = "C:\Scripts\Tests\test3.csv"
    $test3CsvFileResults = "C:\Scripts\Tests\test3Results.csv"

    $column1 = $_.test1ColumnOne
    $column2 = $_.test2ColumnTwo
    $column3 = $_.test3ColumnThree

    GetColumnValues $test1CsvFile $test1CsvFileResults $column1
    GetColumnValues $test2CsvFile $test2CsvFileResults $column2
    GetColumnValues $test3CsvFile $test3CsvFileResults $column3
}

Main

但是,它不是打印出非空值的函数,而是打印一个空白的csv文件。

使用这些csv文件来测试代码......

... csvFile1

test1ColumnOne,test1ColumnTwo,test1ColumnThree
qwer,,
,qwer,
,,qwer

... csvFile2

test2ColumnOne,test2ColumnTwo,test2ColumnThree
asdf,,
,asdf,
,,asdf

... csvFile3

test3ColumnOne,test3ColumnTwo,test3ColumnThree
zxcv,,
,zxcv,
,,zxcv

结果应为......

... test1Results.csv

"test1ColumnOne","test1ColumnTwo","test1ColumnThree"
"qwer","",""

... test2Results.csv

"test2ColumnOne","test2ColumnTwo","test2ColumnThree"
"","asdf",""

... test3Results.csv

"test3ColumnOne","test3ColumnTwo","test3ColumnThree"
"","","zxcv"

2 个答案:

答案 0 :(得分:2)

如果要清除CSV列中的空值,保留该列的非空值列表,请执行以下通用函数:

function Remove-EmptyValues {
  Param(
    [Parameter(
      Mandatory=$true,
      Position=0,
      ValueFromPipeline=$true,
      ValueFromPipelineByPropertyName=$true
    )]
    [object[]]$Csv,
    [Parameter(Mandatory=$true, Position=1)]
    [string]$ColumnTitle
  )

  Process {
    $Csv | Select-Object -Expand $ColumnTitle | Where-Object { $_ }
  }
}

所以它可以像这样使用

$csv = Import-Csv 'C:\testScripts\test.csv'
$noEmpty = Remove-EmptyValues $csv 'column A'

或者像这样:

$csv = Import-Csv 'C:\testScripts\test.csv'
$noEmpty = $csv | Remove-EmptyValues -ColumnTitle 'column A'

编辑:如果要删除特定列中的值为空的所有行,请将输入和输出文件名以及列的名称作为字符串参数传递:

function Remove-EmptyRecords {
  Param(
    [Parameter(Mandatory=$true, Position=0)]
    [string]$Source,
    [Parameter(Mandatory=$true, Position=1)]
    [string]$Destination,
    [Parameter(Mandatory=$true, Position=2)]
    [string]$ColumnTitle
  )

  Import-Csv $Source |
    Where-Object { $_.$ColumnTitle } |
    Export-Csv $Destination -NoType
}

Remove-EmptyRecords test1.csv test1Results.csv test1ColumnOne
Remove-EmptyRecords test2.csv test2Results.csv test2ColumnTwo
Remove-EmptyRecords test3.csv test3Results.csv test3ColumnThree

答案 1 :(得分:0)

不确定你听到的是什么,但你GetColumnValues所以让我们建立一个具有该目标的功能。你有一个columnName参数。还应添加-path一个。

Function Get-ColumnValues{
    Param ($Path, $ColumnName)

    $csvData = Import-Csv $Path
    If($ColumnName -in ($csvData | Get-Member -MemberType "NoteProperty").Name){
        ($csvData).$ColumnName | Where-Object{![string]::IsNullOrEmpty($_)}
    } Else {
        Throw "There is no column present called $ColumnName in the file $Path" 
    }
}

此处可以包含更多错误预防,但只需将其导入csv并返回所请求列的值(假设它存在)。

除非您导出结果,否则您的函数名称会产生误导。你不仅要得到它们,还要设置它们。