Приведенный ниже powershell работает правильно, однако это занимает много времени, например, 10 минут на 50-тысячном строковом csv. Я уверен, что заставляю его работать тяжелее, чем нужно - мне нужно только сопоставить столбец идентификатора, а затем вернуть столбцы для каждого совпадения. Любые идеи о том, как сделать это быстрее или эффективнее?
$ID = @()
$fname = @()
$lname = @()
$mname = @()
$streetadd = @()
$apartment = @()
$city = @()
$state = @()
$zip = @()
$Ids = @(0317,11432,1104,9999,1955)
Write-Host "PLEASE WAIT >>> "
Import-Csv C:\mycsv.csv |`
ForEach-Object {
$ID += $_."ID"
$fname += $_."First Name"
$lname += $_."Last Name"
$mname += $_."Middle Name"
$streetadd += $_."Street Address"
$apartment += $_."Apartment"
$city += $_."City"
$state += $_."State"
$zip += $_."Zip"
}
foreach ($Id in $Ids) {
foreach ($elem in $ID) {
# Write-Host $Id
if ($Id -contains $elem)
{
#Write-Host "Customer Exists!"
$Where = [array]::IndexOf($ID, $elem)
Write-Host $ID[$Where] $fName[$Where] $lname[$Where] $mname[$where] $streetadd[$where] $apartment[$where] $city[$where] $state[$where] $zip[$where]
}
}
}
Попытка использовать приведенный ниже код из ответа ниже @Moerwald и не получить никаких результатов.
$Ids = @(1317,1132,110,9999,1955)
$rows = @(Import-Csv C:\mycsv-csv.csv |? { $Ids -contains $_.id})
foreach ($r in $rows) {
write-host $r.id; $r.fname
}
Какой разделитель используется в вашем CSV-файле? Import-Csv
разделитель по умолчанию — ,
.
да это запятая
Можете ли вы опубликовать содержимое CSV?
это выглядело бы более похоже на это: идентификатор студента, другой идентификатор, имя, фамилия, отчество, дата рождения,,,,,,,, строка адреса улицы 1, строка адреса улицы 2, квартира, город, штат, почтовый индекс 1317, ,a,b,c,11.06.2019,,,,,,,,1 5-й dr,,,main,nv,55555 1132,,d,e,f,10.06.2019,,,,, ,,,7 24-й доктор,,,герцог,аз,55555
Ну, в вашем CSV-файле нет поля id
... Я обновил свой ответ.
$Ids = @(0317,11432,1104,9999,1955)
$rows = @(Import-Csv C:\mycsv.csv |? { $Ids -contains $_.ID})
$rows
будет массивом отфильтрованных строк. Вы можете перебирать массив через:
$rows | % { Write-Host "$($_.Id)"}
$_
ссылается на отфильтрованную строку и имеет свойства, соответствующие именам столбцов.
?
— это ярлык для командлета где-объект.
%
— это ярлык для командлета foreach-объект.
Обновлять:
Этот код работает:
$s =@'
Student ID,OtherID,First Name,Last Name,Middle Name,Birth Date,,,,,,,,Street Address Line 1,Street Address Line 2,Apartment,City,State,Zip
1317,,a,b,c,6/11/2019,,,,,,,,1 5th dr,,,main,nv,55555
1132,,d,e,f,6/10/2019,,,,,,,,7 24th dr,,,duke,az,55555
'@
$csv = convertfrom-csv $s
$Ids = @(1317,1132, 11432,1104,9999,1955)
$rows = $csv |? { $Ids -contains $_.'Student ID'}
$rows | % { $_.'Student ID'}
Это возвращает:
1317
1132
Вот связь для текущей версии.
Я думаю, что это то, что я ищу, но я пытаюсь обдумать это - я пробовал foreach ($ row in $ rows) { $ rows | % { Write-Host "$($_.Id)"} } --- Но, похоже, это не работает?
Оператор %
действует как foreach над rows
, фактический объект присваивается $_
Спасибо за это, но я думаю, что я просто не заставляю его работать - как будет выглядеть foreach? foreach ($elem в $_) {}
foreach ($r in $rows) { $r.Id; $r.fname}
Я обновил свой вопрос кодом, который я пробовал, с 0 результатами
Я бы рекомендовал использовать список массивов, при каждой операции массива
+=
выделяется новый массив при использовании стандартного массива PS. Создайте список массивов черезNew-Object System.Collections.ArrayList
, после чего вы можете вызвать методAdd