Хеш-таблица Powershell не записывает в файл должным образом - получает только строки «System.Collections» - PullRequest
12 голосов
/ 10 мая 2011

Может кто-нибудь объяснить, Почему мои первые примеры не работают, и почему добавление в ForEach-Object решает проблему? Заранее спасибо!


Я проанализировал возврат команды в хеш-таблицу (пример в конце записи) и хочу записать информацию в файл как часть моей обработки. Я знаю, что $ht.GetEnumerator() | Sort-Object Name вернет полный хеш на экран, отсортировано. Тем не менее, как только я пытаюсь отправить вещи в файл, он ломается.

$ht | Add-Content log.txt

регистрирует только одну строку System.Collections.Hashtable. Итак, я также попробовал

$ht.GetEnumerator() | Sort-Object Name | Add-Content log.txt 

и заканчиваются строками

System.Collections.DictionaryEntry
System.Collections.DictionaryEntry
System.Collections.DictionaryEntry

Итак, я попытался перебрать и обработать каждый индивидуально с помощью

foreach ($key in $ht.keys) {
Add-Content log.txt "$key : $ht.$key" }

и заканчивается

Server address : System.Collections.Hashtable.Server address
Client address : System.Collections.Hashtable.Client address
User name : System.Collections.Hashtable.User name

Решено с помощью :

$ht.GetEnumerator() | Sort-Object Name |
ForEach-Object {"{0} : {1}" -f $_.Name,$_.Value} |
Add-Content log.txt 

Для справки, образец хеш-таблицы:

$ht = @{
    "Server address" = "server.net";
    "Client address" = "10.20.121.153";
    "User name" = "myuser"
}

Ответы [ 6 ]

13 голосов
/ 11 мая 2011

Отвечая на вопрос почему , у вас, очевидно, есть решение:)

В вашем первом примере

$ht | Add-Content log.txt

PowerShell принимает $ht и пытается каким-то образом преобразовать его в строку, чтобы его можно было сохранить с помощью Add-Content. Поскольку для хеш-таблицы не определено преобразование, из преобразования возвращается только имя типа. То же, что например new-Object Random|Add-Content d:\log.txt. Опять же, пишется только имя типа.

Далее

$ht.GetEnumerator() | Sort-Object Name | Add-Content log.txt 

похоже. GetEnumerator возвращает объект, который используется для итерации; объекты типа System.Collections.DictionaryEntry возвращаются. Опять же, нет преобразования в строку, поэтому возвращаются имена типов.

Лично я считаю, что PowerShell должен быть достаточно умным и помогать здесь. Вопрос «как?». Дизайнеры, вероятно, не хотели жестко кодировать вывод. Это может быть "{key}: {value}" или "{key} = {value}", или "{key}/{value}", или ... Формат не ясен, поэтому они оставили нам решать и форматировать, как вы сделали это с оператором foreach.

7 голосов
/ 29 июня 2011

Я согласен с mjolinor ... просто недостаточно очков, чтобы проголосовать ... плюс я добавлю, что вам не нужен GetEnumerator

$ht | out-string | add-content log.txt

сделает это.

4 голосов
/ 10 мая 2011

Ваш первый пример не работает, а точнее, частично работает, потому что вы пытаетесь получить значение свойства в строке.Обычно внутри строк анализатор может разрешать только прямые переменные (например, $key).Чтобы разрешить более сложные переменные, вам нужны круглые скобки.

Для цикла это должно работать:

foreach ($key in $ht.keys) {
Add-Content log.txt "$key : $($ht.$key)" }

или даже лучше

$ht.keys | %{ Add-Content log.txt "$_ : $($ht.$_)" }
3 голосов
/ 10 мая 2011

Как видно из документации Microsoft, хеш-таблица - это просто набор пар имя-значение.

Таким образом, $ht действительно System.Collections.Hashtable состоит из System.Collections.DictionaryEntry.

Хороший способ использовать это

foreach ($i in $ht.keys)
{
  add-content log.txt ("{0} {1}" -f $i, $ht[$i])
}
1 голос
/ 10 мая 2011

Как насчет:

 $ht.GetEnumerator() | Sort-Object Name | out-string | Add-Content log.txt 
0 голосов
/ 26 февраля 2018

Вы можете записать «сырой» дамп хеш-таблицы в файл ASCII, используя Out-File:

$data = @{
  Name = "Something"
  Type = "123"
}
$data | Out-File "myfile.txt" -Encoding ascii
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...