Извлечение столбцов из txt файла с двумя разделителями с помощью powershell

у меня есть файл sample.txt

Processing...
Cl.Cog = "/u/l/Cg.txt"
V.DM=Nv
AL.Ft = "He Se Fe",Bt,@L(Ey,0),&Ct:&Cu3

мне нужно разделить этот файл с 4 разными столбцами с новым столбцом, добавленным до вывод.csv

PHP> This is hard coded line;

column1              column2             column3             column4              
+-------------------+-------------------+-------------------+-------------------
abcdefg                Cl                 Cog               "/u/l/Cg.txt"               
abcdefg                V                  DM                   Nv
abcdefg                AL                 Ft                 "He Se Fe",Bt,@L(Ey,0),&Ct:&Cu3

так что я пробовал это, что, похоже, не работает

Get-Content test.txt | 
$headerString = "PHP> This is hard coded line;"

$headerElements = $headerString -split "\s+" | Where-Object{$_}
$headerIndexes = $headerElements | ForEach-Object{$headerString.IndexOf($_)}
$results = $data 
Foreach {"$(($_ -split '\s+',4)[0..2])"} |
Out-file -filepath "D:\output.txt"    

откуда abcdefg в вашем коде? также вам нужно объяснить, что такое разделитель столбцов, поскольку ваш ожидаемый результат и ваш код вообще не связаны

Santiago Squarzon 14.04.2023 04:29

это дополнительный столбец, добавленный ранее с той же строкой (abcdefg) в этом... и мой код, над которым я все еще работаю

Intern99 14.04.2023 04:33

Это неправильный способ обработки данных. Можете ли вы опубликовать больше текстового файла с более чем одним образцом ввода. Одна строка CSV должна содержать несколько строк текстового файла.

jdweng 14.04.2023 04:43
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
73
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Попробуйте следующее:

$inputFilename = 'c:\temp\test.txt'
$outputFilename = 'c:\temp\test.csv'
$contents = Get-Content $filename

$table = [System.Collections.ArrayList]::new()
foreach($row in $contents)
{
   if ($row.Contains('='))
   {
      $newRow = New-Object -TypeName psobject

      $newRow | Add-Member -NotePropertyName column1 -NotePropertyValue 'abcdefg'
      $splitRow = $row.Split('=')
      $splitPeriod = $splitRow[0].Split('.')

      $newRow | Add-Member -NotePropertyName column2 -NotePropertyValue $splitPeriod[0]
      $newRow | Add-Member -NotePropertyName column3 -NotePropertyValue $splitPeriod[1]
      $newRow | Add-Member -NotePropertyName column4 -NotePropertyValue $splitRow[1]

      $table.Add($newRow) | Out-Null
   }
}
$table
$table | export-csv -Path $outputFilename

Ваш ответ не только однотипен для PowerShell и, следовательно, многословен, но и намного медленнее, чем идиоматическое решение. Основываясь на моих тестах на машине с Windows 11 22H2, работающей под управлением Windows PowerShell 5.1 с 1000 строками ввода, примерно в 50 (!) раз медленнее. Я предлагаю вам самостоятельно запустить тесты (также чтобы убедиться, что я правильно измеряю): gist.github.com/mklement0/…

mklement0 02.05.2023 05:15

@mklement0 mklement0: разница во времени - это не стиль программирования. Медленно работает Add-Member. Использование $newRow = [pscustomobject] @{ column1 = 'abcdefg' column2 = $splitPeriod[0] column3 = $splitPeriod[1] column4 = $splitRow[1] } делает мое и ваше время примерно одинаковыми.

jdweng 16.05.2023 13:14

Да, использование повторных вызовов Add-Member, когда один литерал [pscustomobject] будет причиной большей части замедления. Другая неидиоматическая часть заключается в том, чтобы вручную создать список (который вы необъяснимым образом назвали $table) вместо того, чтобы использовать оператор foreach в качестве выражения и позволить PowerShell создать для вас массив. Обе практики (как бы вы их ни называли — я не использовал термин «стиль программирования») сводятся к коду, который не только более многословен, но и в данном случае значительно медленнее.

mklement0 16.05.2023 15:47

Прямое использование API-интерфейсов .NET при правильном использовании может обеспечить повышение производительности (использование [System.Collections.ArrayList] приводит к противоположному результату), но сначала всегда следует пробовать идиоматический высокоуровневый код PowerShell — нет необходимости начинать с API-интерфейсов .NET, а не просто чтобы избежать многословия и более низкого уровня абстракции, а также чтобы не нуждаться в знаниях из отдельной области знаний.

mklement0 16.05.2023 15:53

Цитата из Соображений производительности сценариев PowerShell: «Многие из описанных здесь методов не являются идиоматическими PowerShell и могут снизить удобочитаемость сценария PowerShell. Авторам сценариев рекомендуется использовать идиоматический PowerShell, если производительность не требует иного».

mklement0 16.05.2023 15:53

@mklement0 mklement0: я полностью не согласен с комментарием о читабельности. Код должен легко комментироваться, а объединение всего в одну длинную инструкцию не позволяет комментировать и очень затрудняет отладку.

jdweng 16.05.2023 16:15

Нет необходимости размещать пайплайн на одной строке, и можно легко избежать дозирования: просто заканчивайте каждый сегмент | и продолжайте на следующей строке, что также позволяет размещать комментарии как после, так и между сегментами пайплайна. Блоки сценариев в конвейерах позволяют выполнять отладку, как и внешние конвейеры. Конвейеры без блоков сценариев редко нуждаются в отладке, и при необходимости вы можете проверить промежуточные результаты с помощью -OutVariable. Что еще более важно, ваш аргумент принципиально благовиден: советовать не использовать основные функции и команды языка, очевидно, обречены на провал.

mklement0 16.05.2023 23:44
Ответ принят как подходящий

Я призываю вас не пытаться "создать" csv самостоятельно. Сосредоточьтесь на создании нужных вам объектов, а затем просто экспортируйте их в csv. В вашей строке заголовка больше столбцов, чем в ваших данных, плюс вы не указываете конкретно, что хотите исключить строку processing..., и не учитываете ее в своем примере кода, но желаемый результат не показывает ее. Вот как бы я справился с тем, что, как я полагаю, вам нужно.

# Create the headers for the csv from your hard coded line
$headerString = "PHP> This is hard coded line;"
$headers = -split $headerString

# Get the text content, you can skip 1 here if you need to exclude processing
$data = Get-Content test.txt

# Iterate over each line replacing literal period and equals with a pipe. 
# Combine this with your static first column value and a pipe 
# I chose pipe as a delimiter as your text file had commas but not a pipe
$results = foreach($line in $data){
    # again, this will create a pipe delimited string
    $csv = 'abcdefg|' + ($line -replace '\.|=','|')
    # convert this string to csv with your custom headers
    $csv | ConvertFrom-Csv -Delimiter '|' -Header $headers
}

Весь вывод был собран в $results. Вы можете просмотреть и/или экспортировать прямо сейчас

$results | Format-Table

PHP>    This is  hard                          coded line;
----    ---- --  ----                          ----- -----
abcdefg Cl   Cog /u/l/Cg|txt                              
abcdefg V    DM  Nv                                       
abcdefg AL   Ft  He Se Fe,Bt,@L(Ey,0),&Ct:&Cu3  

# output to csv
$results | Export-Csv Some.csv -NoType

Если вы хотите вывести представление таблицы в текстовый файл (я не рекомендую это делать, csv гораздо проще использовать позже), вы можете сделать это

$results | Format-Table | Out-String | Set-Content c:\temp\textfile.txt

я хочу исключить обработку, а также .. на выходе я получаю нужную таблицу .. как экспортировать ту же таблицу в текстовый файл .. я пробовал out-file .. и export-csv ... он не работает

Intern99 14.04.2023 06:57

' $data = Get-content 'output.txt' $data | foreach {$_.replace('","',' ').TrimStart('"').TrimEnd('"')} $data | Export-Csv -Path 'E:\new_1.txt' -NoType '

Intern99 14.04.2023 07:23

это способ задать фиксированную ширину для каждого столбца в этом текстовом файле таблицы форматов. Application"; ширина = 21}, ` @{Expression = {$_.Name};Label = "Database";ширина=20}, ` @{Expression = {$_.Name};Label = "variable";ширина =20}, @{Expression = {$_.Name};Label = "value";width=20} $width = Get-Process | Format-Table -Property $a |Out-string | Set-Content c:\inal.txt' '

Intern99 25.04.2023 12:31

Другие вопросы по теме