我有一个可能包含未知标头的csv文件,其中一列将包含电子邮件地址。
有没有办法只选择包含电子邮件地址的列并将其作为列表保存到变量?
一个csv可能有标题说电子邮件,另一个可以说emailaddresses,另一个可以说电子邮件地址另一个文件可能甚至没有在标题中的单词电子邮件。如您所见,标题不同。所以我希望能够首先检测正确的列,并在脚本中进一步使用该数据。根据列中包含的数据识别列后,仅选择该列。
我已经尝试过where-object和select-string cmdlet。对于两者,输出是整个数组,而不仅仅是我想要的列中的数据。
$CSV = import-csv file.csv
$CSV | Where {$_ -like "*@domain.com"}
这将输出整个数组,因为所有行都将包含此数据。
答案 0 :(得分:2)
id,first_name,bagel,last_name
1,Base,bcruikshank0@homestead.com,Cruikshank
2,Regan,rbriamo1@ebay.co.uk,Briamo
3,Ryley,rsacase2@mysql.com,Sacase
4,Siobhan,sdonnett3@is.gd,Donnett
5,Patty,pesmonde4@diigo.com,Esmonde
百吉饼显然是我们想要找到的。我们将假装我们不知道列名称或位置提前。
# Import the CSV
$data = Import-CSV $path
# Take the first row and get its columns
$columns = $data[0].psobject.properties.name
# Cycle the columns to find the one that has an email address for a row value
# Use a VERY crude regex to validate an email address.
$emailColumn = $columns | Where-Object{$data[0].$_ -match ".*@*.\..*"}
# Example of using the found column(s) to display data.
$data | Select-Object $emailColumn
基本上像普通一样在CSV中读取并使用第一列数据来尝试找出电子邮件地址列的位置。有一点需要注意,如果有多个匹配的列将返回。
要强制执行仅1个结果,Select-Object -First 1
的简单管道将处理该结果。然后你只需要希望第一个是"对"一。
答案 1 :(得分:0)
如果您正在使用Import-Csv
,则结果为PSCustomObject
。
$CsvObject = Import-Csv -Path 'C:\Temp\Example.csv'
$Header = ($CsvObject | Get-Member | Where-Object { $_.Name -like '*email*' }).Name
$CsvObject.$Header
此过滤器包含email
的标头,然后从对象中选择该列。
编辑要求:
$Str = @((Get-Content -Path 'C:\Temp\Example.csv') -like '*@domain.com*')
$Headers = @((Get-Content -Path 'C:\Temp\Example.csv' -TotalCount 1) -split ',')
$Str | ConvertFrom-Csv -Delimiter ',' -Header $Headers
答案 2 :(得分:0)
其他方法:
$PathFile="c:\temp\test.csv"
$columnName=$null
$content=Get-Content $PathFile
foreach ($item in $content)
{
$SplitRow= $item -split ','
$Cpt=0..($SplitRow.Count - 1) | where {$SplitRow[$_] -match ".*@*.\..*"} | select -first 1
if ($Cpt)
{
$columnName=($content[0] -split ',')[$Cpt]
break
}
}
if ($columnName)
{
import-csv "c:\temp\test.csv" | select $columnName
}
else
{
"No Email column founded"
}