Возьмите это, как вы, это должно объединить несколько файлов CSV. Обратите внимание, что это может быть не быстро, но оно должно быть тщательным.
$CSVList = 'C:\Path\To\Users1.csv','C:\Path\To\Users2.csv','C:\Path\To\Users3.csv','C:\Path\To\Users4.csv','C:\Path\To\Users5.csv'
$PrimaryTable = @{}
Import-CSV $CSVList[0] | %{$PrimaryTable.Add($_.UserID,$_)}
$PrimaryKeys = $PrimaryTable.Values[0] | Get-Member -MemberType Properties | Select -ExpandProperty Name
ForEach($CSVFile in ($CSVList|Select -Skip 1)){
$Users = Import-CSV $CSVFile
$Keys = $Users[0] | Get-Member -MemberType Properties | Select -ExpandProperty Name
$KeysToAdd = @{}
$Keys|?{$_ -notin $PrimaryKeys}|%{$KeysToAdd.Add($_,"")}
$PrimaryTable.Values|%{$_|Add-Member -NotePropertyMembers $KeysToAdd}
ForEach($User in $Users){
If(!($User.UserID -in $PrimaryTable.Keys)){
$PrimaryKeys | ?{$_ -notin $Keys} | %{add-member -InputObject $User -NotePropertyName $_ -NotePropertyValue ""}
$PrimaryTable.Add($User.UserID,$User)
}Else{
$Keys | ?{[string]::IsNullOrWhiteSpace($PrimaryTable.($User.UserID).$_)} | %{$PrimaryTable.($User.UserID).$_ = $User.$_}
}
}
$PrimaryKeys = $PrimaryTable.Values[0] | Get-Member -MemberType Properties | Select -ExpandProperty Name
}
$PrimaryTable.Values|Export-CSV C:\Path\To\AllUserData.csv -NoTypeInformation
Это делает хэш-таблицу индексированной с идентификатора пользователя. Он заполняет его данными из первого файла CSV. Затем для каждого дополнительного он проверяет различия в свойствах того, что находится в первом CSV и текущем, добавляет недостающие свойства ко всем элементам в главной хеш-таблице, затем идет запись по записи, и если пользователь не находится в главная хэш-таблица добавляет их, и если они тогда, то она заполняет любые пробелы, которые она может для своих свойств.
Редактировать: Итак, у вас возникли проблемы с оператором -notin
. Наиболее вероятной причиной этого является более старая версия PowerShell. Мое первое предложение - обновить до версии v3 или v4 PowerShell, но я знаю, что это не всегда вариант, поэтому, чтобы сделать это немного более обратной совместимости, я внес некоторые изменения в скрипт, который должен заставить его работать на вас ... Я надеюсь. Я проверил вышеприведенный сценарий (с обновленными путями в строке 1, и я прокомментировал последнюю строку, потому что мне не хотелось, чтобы мой жесткий диск заставлял загружать еще больше файлов) с 3 файлами CSV, у которых все поля UserID, и каждый имел от 2 до 4 записей, и он работал точно так, как я ожидал. Во всяком случае, отредактированный сценарий:
$CSVList = 'C:\Path\To\Users1.csv','C:\Path\To\Users2.csv','C:\Path\To\Users3.csv','C:\Path\To\Users4.csv','C:\Path\To\Users5.csv'
$PrimaryTable = @{}
Import-CSV $CSVList[0] | %{$PrimaryTable.Add($_.UserID,$_)}
$PrimaryKeys = $PrimaryTable.Values[0] | Get-Member -MemberType Properties | Select -ExpandProperty Name
ForEach($CSVFile in ($CSVList|Select -Skip 1)){
$Users = Import-CSV $CSVFile
$Keys = $Users[0] | Get-Member -MemberType Properties | Select -ExpandProperty Name
$KeysToAdd = @{}
$Keys|?{$PrimaryKeys -notcontains $_}|%{$KeysToAdd.Add($_,"")}
$PrimaryTable.Values|%{$_|Add-Member -NotePropertyMembers $KeysToAdd}
ForEach($User in $Users){
If(!($User.UserID -in $PrimaryTable.Keys)){
$PrimaryKeys | ?{$Keys -notcontains $_} | %{add-member -InputObject $User -NotePropertyName $_ -NotePropertyValue ""}
$PrimaryTable.Add($User.UserID,$User)
}Else{
$Keys | ?{[string]::IsNullOrWhiteSpace($PrimaryTable.($User.UserID).$_)} | %{$PrimaryTable.($User.UserID).$_ = $User.$_}
}
}
$PrimaryKeys = $PrimaryTable.Values[0] | Get-Member -MemberType Properties | Select -ExpandProperty Name
}
$PrimaryTable.Values|Export-CSV C:\Path\To\AllUserData.csv -NoTypeInformation
Это должно делать то, что вы хотите, и должно работать в более старых версиях PowerShell. Дайте мне знать, если у вас есть ошибки. Опять же, моя рекомендация - обновить PowerShell, если вы используете v2. Вы будете счастливее в долгосрочной перспективе, чем работать вокруг.
Лично я мог бы импортировать их в базу данных SQL и присоединиться к таблицам. Как бы то ни было, вы можете взглянуть на [Join-Object] (http://blogs.msdn.com/b/powershell/archive/2012/07/13/join-object.aspx). –
Я дал ответ примерно на тот же вопрос [здесь] (http://stackoverflow.com/a/17027718/608772). – JPBlanc
Блог о соединении-объекте просто поместился в моем списке избранных. Я намерен читать и учиться этому. Первая часть, по-видимому, представляет собой обзор первой, второй и третьей нормальных форм, хотя и не говорит об этом. Благодаря! –