2015-12-21 46 views
1

我有很多重複的代碼,我想清理。我知道下面的語法是不正確的,但是你能讓我知道正確的方法嗎?比方說,我有以下代碼...如何通過函數參數傳遞csv列對象

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" 
+0

'(進口-CSV $文件)。 ColumnName' ....從某種意義上說是列對象。你想要名稱還是位置?你只想要值或對象列? – Matt

+0

沒有「列對象」。 CSV值被讀入對象的屬性中,其中每個對象代表CSV的一行。你的代碼應該做什麼?你想刪除空字段的行嗎?在特定列中有空字段的行?僅提取一列並刪除空值? 「正確的語法」取決於期望的結果。 –

+0

我更新了問題。讓我知道它是否仍然沒有意義。要回答你的問題,我的代碼應該做什麼,我有很多腳本利用這段代碼用於不同的目的。但代碼重複有點極端,我想知道是否有一種方法可以通過'$ _。name'作爲函數的參數。 –

回答

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 
+0

Hi Ansgar,我只是再次更新了這個問題......所以我真的很關心獲取空值,因爲我在乎''傳遞'$ _。通過函數'Param($ _。columnName)'來創建columnName。我有搜索用戶輸入的字符串爲每個列的函數,我有函數將列值與csv文件之間的其他列值相匹配。如果有一種方法通過函數參數傳遞'$ _。columnName',所有代碼都可以被簡化。有沒有辦法做到這一點? –

+0

@FiddleFreak你想要傳遞一列的*標題*或一列的*值*嗎? –

+0

只是標題,價值將是功能的工作,找出。 –

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並返回請求的列的值,假設它的存在。

另外,如果您要導出結果,函數的名稱會令人誤解。你不僅得到它們,而且還設定它們。

+0

我更新了這個問題,同時注意'if($ _。test1ColumnOne){$ _。test1ColumnOne}'將返回該列中的值,只要它不爲空或空字符串。 –

+0

@FiddleFreak是的。我明白代碼的作用。 'IsNullOrEmpty'更易於閱讀和理解。如果你堅持我會這樣做,它會做同樣的事情'Where-Object {$ _}' – Matt

+0

'[string] :: IsNullOrWhiteSpace'可能會更好,如果你也擔心這些。我通常只是使用'Where-Object {$ _}'或類似的東西 – Matt

相關問題