Я хочу преобразовать текстовый файл в файл CSV, а ниже приведен формат с использованием Powershell, и мне нужна помощь.
Содержание для справки:
Quantity: 30
Manufacturer: Microsoft
License metric: Microsoft Core Infrastructure Server Suite Datacenter Core
Expiry: 31/12/2024
Quantity: 70
Manufacturer: Microsoft
License metric: Microsoft Windows Server Datacenter Core (SA)
Expiry: 31/12/2025
Quantity: 58
Manufacturer: Microsoft
License metric: Microsoft Core Infrastructure Server Suite Datacenter Core
Expiry: 31/12/2024
Преобразование текстового файла в CSV (в строки и столбцы) Заголовок CSV: количество, производитель, показатель лицензии, срок действия.
@DavidMakogon: Хотя всегда предпочтительнее, чтобы вопрос демонстрировал попытку решения, это не является строго необходимым, если проблема полностью определена - как в рассматриваемом случае. В конце концов, если предположить, что проблема представляет общий интерес, сообщество по-прежнему выигрывает, если есть ответы с работающими решениями, будущих читателей не будет волновать, содержит ли сам вопрос попытку решения. Таким образом, если на вопрос уже есть принятый ответ/ответы с рабочими решениями, нет смысла задним числом настаивать на том, чтобы ФП продемонстрировал попытку решения.





Чтобы преобразовать текстовый файл в файл CSV, вы можете использовать следующий сценарий PowerShell:
$inputFile = "file1.txt"
$outputFile = "fileout1.csv"
$inputLines = Get-Content $inputFile
$outputLines = @("Quantity,Manufacturer,License metric,Expiry")
for ($i = 0; $i -lt $inputLines.Length; $i += 4) {
$quantity = $inputLines[$i] -replace "Quantity: "
$manufacturer = $inputLines[$i+1] -replace "Manufacturer: "
$licenseMetric = $inputLines[$i+2] -replace "License metric: "
$expiry = $inputLines[$i+3] -replace "Expiry: "
$outputLines += "$quantity,$manufacturer,$licenseMetric,$expiry"
}
$outputLines | Out-File $outputFile
Обязательно замените переменные $inputFile и $outputFile фактическими путями к входным и выходным файлам. Этот сценарий считывает входной файл, разбивает строки на столбцы и записывает выходные данные в файл CSV с указанным заголовком.
Выход:

Quantity,Manufacturer,License metric,Expiry
30,Microsoft,Microsoft Core Infrastructure Server Suite Datacenter Core,31/12/2024
70,Microsoft,Microsoft Windows Server Datacenter Core (SA),31/12/2025
58,Microsoft,Microsoft Core Infrastructure Server Suite Datacenter Core,31/12/2024
Спасибо Асвину за то, что поделились, но, похоже, у меня это не работает: Вывод ниже: Количество, Производитель, Показатель лицензии, Срок действия 30, Microsoft, Microsoft Core Infrastructure Server Suite Datacenter Core, 31/12/2024, Количество: 70, Производитель: Microsoft, Лицензия метрика: Microsoft Windows Server Datacenter Core (SA). Срок действия: 31.12.2025,,Количество: 58,Производитель: Microsoft. Метрика лицензии: Microsoft Core Infrastructure Server Suite Datacenter Core,Срок действия: 31.12.2024,,
Заголовок и первая запись отображаются нормально, но добавляются количество, производитель и т. д. с данными из второй строки вывода.
Не уверен, почему заголовок появляется вместе с каждой строкой вашего вывода. Я получил результат, как вы и ожидали. См. скриншот в ответе. Я еще раз проверю свое окружение.
Примечание:
Если сохранение порядка ввода свойств не важно, можно воспользоваться более простым способом
Решение на основе ConvertFrom-StringData возможно, как показано в ответе Дуга Маурера.
Проблема GitHub № 19070 — это запрос функции, позволяющий ConvertFrom-Json вместо этого создавать упорядоченные хеш-таблицы, которые затем сохранят порядок ввода.
Я предлагаю обработать ваш файл с помощью оператора regex на основе -split:
# Create an ordered helper hashtable to help with [pscustomobject] construction
$oht = [ordered] @{}
# Split the input file into blocks of lines, and process each block.
(Get-Content -Raw file.txt) -split '\r?\n\r?\n' -ne '' | ForEach-Object {
$oht.Clear() # Clear the helper hashtable to start constructing a new object.
# Split the block at hand into individual lines and process each.
$_ -split '\r?\n' -ne '' | ForEach-Object {
# Split the line at hand into property name and value...
$name, $value = $_ -split ':', 2
# ... and add this property-name pair to the helper hashtable.
$oht[$name] = $value.Trim()
}
# Construct a [pscustomobject] from the helper hashtable and output it.
[pscustomobject] $oht
} # | Export-Csv ... # Add your Export-Csv call here.
Отображение вывода, показывающего построенные объекты и их свойства, используя неявное форматирование таблицы:
Quantity Manufacturer License metric Expiry
-------- ------------ -------------- ------
30 Microsoft Microsoft Core Infrastructure Server Suite Datacenter Core 31/12/2024
70 Microsoft Microsoft Windows Server Datacenter Core (SA) 31/12/2025
58 Microsoft Microsoft Core Infrastructure Server Suite Datacenter Core 31/12/2024
Примечание:
Это решение работает с любым текстовым файлом аналогичного формата (где каждый непрерывный блок строк представляет объект, а имена и значения свойств разделены знаком : и не заключаются в кавычки) независимо от конкретных имен свойств.
Благодаря использованию регулярного выражения \r?\n для сопоставления новых строк (разрывов строк) поддерживаются как файлы формата Windows с символами новой строки CRLF, так и файлы формата Unix с символами новой строки только LF.
Для каждого блока строк используется упорядоченная хеш-таблица ([ordered] @{}) для сбора пар свойств-значений этого блока.
Приведение этой хэш-таблицы к [pscustomobject] создает экземпляр последней, подходящий для передачи по конвейеру в Export-Csv.
Если порядок свойств не имеет значения, вы можете воспользоваться ConvertFrom-StringData, чтобы упростить эту задачу. Github Issue #19070 предлагает исправить эту проблему.
Для PowerShell 6+, который предлагает параметр -Delimiter, мы можем обрабатывать его как есть.
# Get all the text data in one string
$data = Get-Content textfile.txt -Raw
# split on repeating new lines to get the blocks of text
$blocks = $data -split '\r?\n\r?\n'
# process each block
$blocks | Foreach-Object {
# cast the resulting hash table to pscustomobject
[PSCustomObject]($_ | ConvertFrom-StringData -Delimiter ':')
}
В PowerShell 5.1 нам нужно заменить двоеточие знаком равенства.
# Get all the text data in one string
$data = Get-Content textfile.txt -Raw
# split on repeating new lines to get the blocks of text and replace the first found colon on each line with an equals character
$blocks = $data -split '\r?\n\r?\n' -replace '(?m)(?<=^[^:]+):','='
# process each block
$blocks | Foreach-Object {
# cast the resulting hash table to pscustomobject
[PSCustomObject]($_ | ConvertFrom-StringData)
}
Оба должны произвести этот результат
License metric Expiry Quantity Manufacturer
-------------- ------ -------- ------------
Microsoft Core Infrastructure Server Suite Datacenter Core 31/12/2024 30 Microsoft
Microsoft Windows Server Datacenter Core (SA) 31/12/2025 70 Microsoft
Microsoft Core Infrastructure Server Suite Datacenter Core 31/12/2024 58 Microsoft
Пожалуйста, прочитайте Как задавать вопросы и как предоставить минимальный воспроизводимый пример. Сейчас вы предоставили только набор требований.