Powershell - вывод данных .txt в CSV - PullRequest
0 голосов
/ 06 июля 2018

Надеюсь, вы могли бы помочь начинающему PowerShell в выводе данных из файла .txt в CSV.

Что нужно иметь в виду:

  • Каждый текстовый файл содержит более одной записи, которую нужно извлечь
  • Терминал всегда будет A, за которым следуют 3 цифры
  • Enquirer всегда будет начинаться с C, но может иметь различную длину
  • В файле есть два шаблона даты рождения
  • Пробелы не разделены символом табуляции в текстовом формате и не являются одинаковыми интервалами.

Это вывод CSV, который я хотел бы (извинения, у меня недостаточно репутации, чтобы загрузить картинку!)

+------------+------+----------+----------+-------------------+----------+
| Date       | Time | Terminal | Enquirer | Enquiry           | DOB      |
+------------+------+----------+----------+-------------------+----------+
| 29/05/2017 | 1227 | A999     | CA75849  | DOE/JOHN          |  / /1988 |
+------------+------+----------+----------+-------------------+----------+
| 29/05/2017 | 1424 | A999     | CA75849  | SMITH/SIMON/PETER |  / /1967 |
+------------+------+----------+----------+-------------------+----------+
|            |      |          |          |                   |          |
+------------+------+----------+----------+-------------------+----------+

Пример файла данных .txt

START                 TERMINAL    USER        ENQUIRER                  TERMINAL IP

========================================================================================================================

29/05/17 1227       A999        CA75849       8875849 OCBA NCPS RBC/12/1960



        SEARCH REF                      NAME : DOE/JOHN PAGE CODE =  

                                    DATE OF BIRTH :   /  /1988




========================================================================================================================
29/05/17 1424       A999        CA75849       8875849 OCBA NCPS RBC/60/2111                                

        SEARCH REF                        NAME : SMITH/SIMON/PETER CHAPTER CODE =  

                                    DATE OF BIRTH :   /  /1967


========================================================================================================================

Пожалуйста, не падайте в обморок от моего дерьмового сценария Powershell.

Лучшее, что мне удалось получить, - это иметь правильную информацию, но System.Object [] в ячейках, а не фактическую строку результатов.

$XmlDocument = Get-Content -Path "C:\Script Projects\Log\880006.txt"
$TodaysCSV = "C:\Script Projects\Log\880006.csv"

$TopLine = $XmlDocument | Select-String "A1" 
$Enquiry = $XmlDocument | Select-String "Search"
$DOB = $XmlDocument | Select-String "BIRTH"

$toptop = $topline -split " "

$Date = $toptop | Select-String -Pattern "^\d{2}/\d{2}/\d{2}$"
$Time = $toptop | Select-String -Pattern "^\d{4}$"
$Terminal = $toptop | Select-String -Pattern "^A\d{3}$"
$Enquirer = $toptop | Select-String -Pattern "C\w\d{5}" 

$csv = New-Object -TypeName PSObject 

Add-Member -InputObject $csv -MemberType NoteProperty -Name "Date"  -Value $Date
Add-Member -InputObject $csv -MemberType NoteProperty -Name "Time"  -Value $Time
Add-Member -InputObject $csv -MemberType NoteProperty -Name "Terminal"  -value $Terminal
Add-Member -InputObject $csv -MemberType NoteProperty -Name "Enquirer"  -value $Enquirer
Add-Member -InputObject $csv -MemberType NoteProperty -Name "Enquiry"  -value $Enquiry
Add-Member -InputObject $csv -MemberType NoteProperty -Name "DOB"  -value $DOB


$csv | Export-Csv $TodaysCSV -NoTypeInformation

Я получаю этот вывод

    +-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| Date            | Time            | Terminal        | Enquirer        | Enquiry         | DOB             |
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| System.Object[] | System.Object[] | System.Object[] | System.Object[] | System.Object[] | System.Object[] |
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
|                 |                 |                 |                 |                 |                 |
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
|                 |                 |                 |                 |                 |                 |
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+

Я тоже так пробовал, но у меня есть только дата или игра, я могу получить все данные, но только в одном столбце

$Total2 = "$date2", "$time2", "$Terminal2", "$Enquirer", "$Enquiry" 

$Columns = "Date", "Time", "Terminal", "Enquirer", "Enquiry"

$total2 | ConvertFrom-Csv -Header $Columns| export-csv $TodaysCSV -NoTypeInformation

Но не могу вспомнить, как я это сделал, и все равно не могу отобразить его по горизонтали, если я импортирую этот файл обратно в PowerShell и экспортирую как CSV.

Лучшее, что мне удалось получить, это

Date    
----    
29/05/17
29/05/17




Time
----
1227
1424




Terminal
--------
A999    
A999    




Enquirer
--------
CA75849 
CA75849 




Enquiry                                                                         
-------                                                                         
SEARCH REF                      NAME : DOE/JOHN CHAPTER CODE =        
SEARCH REF                      NAME : SMITH/SIMON/PETER CHAPTER CODE = 

Заранее спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

Я использовал другой подход,

  • разбиение файла на разделы, разделенные штриховой линией и
  • 3 различных регулярных выражения, использующих именованные (группы захвата), для сопоставления свойств каждого типа линии.
    Первый на RegEx101.com
  • все найденные свойства хранятся в промежуточном объекте $ Row и, если все совпадения RegEx собраны в $Csv

## Q:\Test\2018\07\06\SO_51209341.ps1
$FileIn   = '.\SO_51209341_data.txt'
$TodayCsv = '.\SO_51209341_data.csv'

$RE1 = [RegEx]'(?m)(?<Date>\d{2}\/\d{2}\/\d{2}) (?<Time>\d{4}) +(?<Terminal>A\d{3}) +(?<User>C[A-Z0-9]+) +(?<Enquirer>.*)$'
$RE2 = [RegEx]'\s+SEARCH REF\s+NAME : (?<Enquiry>.+?) (PAGE|CHAPTER) CODE ='
$RE3 = [RegEx]'\s+DATE OF BIRTH : (?<DOB>[0-9 /]+?/\d{4})'

$Sections = (Get-Content $FileIn -Raw) -split "={30,}`r?`n" -ne ''

$Csv = ForEach($Section in $Sections){
    $Row= @{} | Select-Object Date,Time,Terminal,User,Enquirer,Enquiry,DOB
    $Cnt = 0
    If ($Section -match $RE1){++$Cnt
        $Row.Date     = $Matches.Date
        $Row.Time     = $Matches.Time
        $Row.Terminal = $Matches.Terminal
        $Row.User     = $Matches.User
        $Row.Enquirer = $Matches.Enquirer.Trim()
    }
    If ($Section -match $RE2){++$Cnt
        $Row.Enquiry  = $Matches.Enquiry
    }
    If ($Section -match $RE3){++$Cnt
        $Row.DOB      = $Matches.DOB
    }
    if ($Cnt -eq 3){$Row}
}

$csv | Format-Table
$csv | Export-Csv $Todaycsv -NoTypeInformation

Пример вывода исправленная версия

> . Q:\Test\2018\07\06\SO_51209341.ps1

Date     Time Terminal User    Enquirer                      Enquiry           DOB
----     ---- -------- ----    --------                      -------           ---
29/05/17 1227 A999     CA75849 8875849 OCBA NCPS RBC/12/1960 DOE/JOHN            /  /1988
29/05/17 1424 A999     CA75849 8875849 OCBA NCPS RBC/60/2111 SMITH/SIMON/PETER   /  /1967
0 голосов
/ 06 июля 2018

Проблема здесь в том, что вам нужно преобразовать объекты в строку перед экспортом.

Чтобы ваш код работал, вы можете немного изменить создание объекта:

$csv = @()
for ($i = 0;$i -lt $Date.Length; $i++) {
$obj = New-Object -TypeName PSObject 
  Add-Member -InputObject $obj -MemberType NoteProperty -Name "Date"  -Value $Date[$i]
  Add-Member -InputObject $obj -MemberType NoteProperty -Name "Time"  -Value $Time[$i]
  Add-Member -InputObject $obj -MemberType NoteProperty -Name "Terminal"  -value $Terminal[$i]
  Add-Member -InputObject $obj -MemberType NoteProperty -Name "Enquirer"  -value $Enquirer[$i]
  Add-Member -InputObject $obj -MemberType NoteProperty -Name "Enquiry"  -value $Enquiry[$i]
  Add-Member -InputObject $obj -MemberType NoteProperty -Name "DOB"  -value $DOB[$i]
  $csv += $obj
}

Пояснение:

Проблема здесь в том, что вы пытаетесь создать объект из массивов, в то время как вы должны создать массив объектов. Вот почему при экспорте вы получили System.Object[] вместо ожидаемого значения.

Примечание : посмотрите на вставленный здесь код и формат файла. Эта строка:

$TopLine = $XmlDocument | Select-String "A1" 

должно быть

$TopLine = $XmlDocument | Select-String "A999" 
...