匹配哈希表中的值,同时忽略两个CSV文件之间的区分大小写

时间:2015-12-16 22:32:40

标签: csv powershell powershell-v3.0

我正在尝试通过查看CSV file1中列的值是否包含在CSV file1中来附加列。

我有一个CSV文件1(test1.csv):

csv1ColumnOne,csv1ColumnTwo
1,dF3aWv
2,
3,ka21p
4,NAE31
5,dsafl
6,nv02k
7,qng02
8,xcw3r
9,dF3aW

我有一个CSV文件2(test2.csv):

csv2ColumnOne,csv2ColumnTwo
bbetfe,DF3AW
asdf,dsafl
qwer,
zxcv,NAE31
poiu,nbrwp1

鉴于以下代码......

$hashTable = @()
Import-Csv C:\path\test1.csv | ForEach-Object {
  $hashTable[$_.csv1ColumnOne] = $_.csv1ColumnTwo
}

(Import-Csv C:\path\test2.csv) |
  Select-Object -Property *, @{n='csv1ColumnThree';e={
    if ($hashTable.ContainsKey($_.csv2ColumnTwo)) {
      $_.csv2ColumnTwo
    } elseif (-not ($_.csv2ColumnTwo)) {
      'No value found from csv file2'
    } else {
      'No value found from csv file1'
    }
  }} | Export-Csv "C:\path\testresults.csv" -NoType

结果如下:

csv2ColumnOne,csv2ColumnTwo,csv1ColumnThree
bbetfe,DF3AW,"No value found from csv file1"
asdf,dsafl,dsafl
qwer,,No value found from csv file2
zxcv,NAE31,NAE31
poiu,nbrwp1,"No value found from csv file1"

相反,它应该是这样的:

csv2ColumnOne,csv2ColumnTwo,csv1ColumnThree
bbetfe,DF3AW,dF3aW
asdf,dsafl,dsafl
qwer,,"No value found from csv file2"
zxcv,NAE31,NAE31
poiu,nbrwp1,"No value found from csv file1"

我看到bbetfe,DF3AW,"No value found from csv file1" ins't bbetfe,DF3AW,dF3aW的原因是因为值的区分大小写。无论如何要忽略具有字母数字值的区分大小写?

4 个答案:

答案 0 :(得分:3)

为避免将字符串转换为小写,只需使用-icontains比较运算符(" i"表示不区分大小写的比较):

所以而不是

If ($hashTable.ContainsKey($_.csv2ColumnTwo)){

试试这个:

If ($hashTable.keys -icontains $_.csv2ColumnTwo){

答案 1 :(得分:3)

ContainsKey()的查找已不区分大小写。您只是使用错误的数据结构,并以错误的方式使用它。

如果要在哈希表中查找,则需要实际使用要查找的数据作为哈希表的

$hashTable[$_.csv1ColumnTwo] = $_.csv1ColumnOne

要在哈希表的中查找某些内容,请使用ContainsValue()

但是,由于您只想检查第一个CSV的第二列是否包含第二个CSV的第二列中的值,因此您首先不需要哈希表。一个简单的数组就足够了。

$list = Import-Csv 'C:\path\test1.csv' | Select-Object -Expand csv1ColumnTwo

Import-Csv 'C:\path\test2.csv' |
  Select-Object -Property *, @{n='csv1ColumnThree';e={
    if ($list -contains $_.csv2ColumnTwo) {
      $_.csv2ColumnTwo
    } elseif (-not ($_.csv2ColumnTwo)) {
      'No value found from csv file2'
    } else {
      'No value found from csv file1'
    }
  }} | Export-Csv 'C:\path\testresults.csv' -NoType

如果你不想要空字符串"发现"在第二个CSV中,只需从$list

中排除该元素
$list = Import-Csv 'C:\path\test1.csv' |
        Select-Object -Expand csv1ColumnTwo |
        Where-Object { $_ }  # allow only non-empty values

并非所有问题都是钉子,所以不要试图用锤子修理所有问题。

答案 2 :(得分:1)

你能把它们全部小写吗?

$a = ipcsv 'C:\path\test1.csv'
$a | % {$_.csv1columntwo = $_.csv1columntwo.tolower()}
$a

$b = ipcsv 'C:\path\test2.csv'
$b | % {$_.csv2ColumnOne = $_.csv2ColumnOne.tolower(); $_.csv2ColumnTwo = $_.csv2ColumnTwo.tolower()}
$b

答案 3 :(得分:1)

Ansgar基本上有正确的答案,但有一个错误。它将第二个文件中的行打印为qwer,,,而应该打印qwer,,No value found from csv file2。还需要在第一个if语句中添加另一个条件,如下所示。

$list = Import-Csv 'C:\path\test1.csv' | Select-Object -Expand csv1ColumnTwo

Import-Csv 'C:\path\test2.csv' |
  Select-Object -Property *, @{n='csv1ColumnThree';e={
    if (($list -contains $_.csv2ColumnTwo) -and ($_.csv2ColumnTwo)) {
      $_.csv2ColumnTwo
    } elseif (-not ($_.csv2ColumnTwo)) {
      'No value found from csv file2'
    } else {
      'No value found from csv file1'
    }
}} | Export-Csv 'C:\path\testresults.csv' -NoType

第二个文件中的空值被检查为true,因此从未到达elseif。