Powershell - запись таблицы Ha sh в файл с массивом - PullRequest
1 голос
/ 16 апреля 2020

Я хотел бы записать таблицу ha sh в файл с массивом в качестве одного из элементов таблицы ha sh. Мой элемент массива записан, но он содержит файлы .

clear-host
$resumeFile="c:\users\paul\resume.log"
$files = Get-ChildItem *.txt
$files.GetType()
write-host
$types="txt"
$in="c:\users\paul"

Remove-Item $resumeFile -ErrorAction SilentlyContinue
$resumeParms=@{}
$resumeParms['types']=$types
$resumeParms['in']=($in)
$resumeParms['files']=($files)
$resumeParms.GetEnumerator() | ForEach-Object {"{0}={1}" -f $_.Name,$_.Value} | Set-Content $resumeFile
write-host "Contents of $resumefile"
get-content $resumeFile

Результаты

IsPublic IsSerial Name                                     BaseType                                                      
-------- -------- ----                                     --------                                                      
True     True     Object[]                                 System.Array                                                  

Contents of c:\users\paul\resume.log
files=System.Object[]
types=txt
in=c:\users\paul

1 Ответ

1 голос
/ 16 апреля 2020

Немедленное исправление состоит в том, чтобы создать собственное представление массива , перечислив элементы и разделив их ,, включив строковые значения в '...':

# Sample input hashtable. [ordered] preserves the entry order.
$resumeParms = [ordered] @{ foo = 42; bar = 'baz'; arr = (Get-ChildItem *.txt) }

$resumeParms.GetEnumerator() |
  ForEach-Object { 
    "{0}={1}" -f $_.Name, (
      $_.Value.ForEach({ 
       (("'{0}'" -f ($_ -replace "'", "''")), $_)[$_.GetType().IsPrimitive] 
      }) -join ','
    )
  }

Не что это представляет все не примитивные. NET типы в виде строк , их представлением .ToString(), которое может быть или не быть достаточно хорошим.

Вышеприведенное выводит что-то вроде:

foo=42
bar='baz'
arr='C:\Users\jdoe\file1.txt','C:\Users\jdoe\file2.txt','C:\Users\jdoe\file3.txt'

См. Нижний раздел для варианта, который создает файл *.psd1, который впоследствии может быть прочитан обратно в экземпляр хеш-таблицы с Import-PowerShellDataFile.


Альтернативы для сохранения настроек / данных конфигурации в текстовых файлах:

  • Если вы не возражаете против использования зависимости от стороннего модуля :

    • Рассмотрите возможность использования модуля PSIni, в котором используется формат файла Windows файла инициализации (*.ini) ; см. этот ответ для примера использования.

      • Добавление поддержки файлов инициализации в сам PowerShell (отсутствует на 7.0) предлагается в этой проблеме GitHub .
    • Подумайте об использовании YAML в качестве формата файла; например, через модуль FXPSYaml.

      • Добавление поддержки файлов YAML в сам PowerShell (отсутствует на 7.0) предлагается в этой проблеме GitHub .
    • Модуль Configuration предоставляет команды для записи и чтения из *.psd1 файлов на основе persisted PowerShell литералы хеш-таблицы , как вы могли бы объявить их в исходном коде.

      • В качестве альтернативы, вы можете изменить формат вывода в коде в верхний, чтобы создавать такие файлы самостоятельно, что позволяет вам читать их обратно через
        Import-PowerShellDataFile, как показано в нижней части.

      • Как в PowerShell 7.0 нет встроенной поддержки для записи , такой как представление; то есть, нет дополнительного Export-PowerShellDataFile командлета. Тем не менее, добавление этой возможности предлагается в этом выпуске GitHub .

  • Если создание ( в основном) простой текст файл не обязательный :

    • Решение, обеспечивающее наибольшую гибкость в отношении данных Поддерживаемые типы * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 11 * * * * * * 11 * * *] [11] с Import-Clixml.
      Однако этот формат также имеет ограничения в отношении точности воспроизведения , как объяснено в этого ответа .

    • Сохранение JSON представления данных, как предполагает Ли, через ConvertTo-Json, является еще одним вариантом, который удобнее для вывода, чем XML, но все же не так дружелюбно, как текстовое представление; В частности, все \ символов. в путях к файлам необходимо экранировать как \\ в JSON.


Запись файла *.psd1, который можно прочитать с помощью Import-PowerShellDataFile

В рамках заявленных ограничений относительно типов данных - по сути, все, что не является числом или строкой, становится строкой - довольно просто изменить код вверху записать представление хеш-таблицы-литерала PowerShell в *.psd1 файл , чтобы его можно было прочитать как экземпляр [hashtable] через Import-PowerShellDataFile:

Как уже отмечалось, если вы не возражаете против установки модуля, рассмотрите модуль Configuration, в который встроена эта функция.

# Sample input hashtable.
$resumeParms = [ordered] @{ foo = 42; bar = 'baz'; arr = (Get-ChildItem *.txt) }

# Create a hashtable-literal representation and save it to file settings.psd1
@"
@{
$(
  ($resumeParms.GetEnumerator() |
    ForEach-Object { 
      "  {0}={1}" -f $_.Name, (
        $_.Value.ForEach({ 
          (("'{0}'" -f ($_ -replace "'", "''")), $_)[$_.GetType().IsPrimitive] 
         }) -join ','
      )
    }
  ) -join "`n"
)
}
"@ > settings.psd1

Если вы прочитаете settings.psd1 с Import-PowerShellDataFile settings.psd1 позже, вы получите [hashtable] экземпляр, к записям которого у вас есть доступ, как обычно, и который выдает следующий вывод:

Name                           Value
----                           -----
bar                            baz
arr                            {C:\Users\jdoe\file1.txt, C:\Users\jdoe\file1.txt, C:\Users\jdoe\file1.txt}
foo                            42

Обратите внимание, как порядок записей (ключей) был не сохранен, потому что записи хеш-таблицы по своей природе неупорядочены.

При записи файла *.psd1 вы можете сохранить порядок ключей (-creation), объявив входную хеш-таблицу (System.Collections.Hashtable) как [ordered], как показано выше (который создает экземпляр System.Collections.Specialized.OrderedDictionary), но, к сожалению, порядок теряется при чтении файла *.psd1.

Начиная с PowerShell 7.0, даже если вы поместите [ordered] перед открытием @{ в *.psd1 файле , Import-PowerShellDataFile тихо проигнорирует его и, тем не менее, создаст неупорядоченный хеш-таблицу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...