Скрипт Powershell для извлечения текста из нескольких строк в одну строку - PullRequest
0 голосов
/ 06 ноября 2019

Мне нужно извлечь некоторые текстовые строки из текстового файла через powershell в новый выходной файл на основе некоторых критериев, а затем также извлечь некоторые данные следующей строки в ту же строку.

ЭтоПример текстового файла:

0 CARDHOLDER NUMBER     TOKEN NUMBER          MESSAGE DATE/TIME    ACTIVITY REASON            NTWK   PAN EXP  TRAN ID                
0 1234567890123456      4234567890123456      11/12/14  15:34:38   T1-TKN CREATE              VSN     49/12   314316099993286        
     TOKEN DATA: EXP DATE: 16/05   REQUESTOR ID: 45432112345   TYPE: T0   STATUS: I   ASSURANCE LEVEL: 16   REQUEST METHOD: 6        
                 TOKEN REF ID: TOKENREFERENCEDATAID012345678901 PAN REF ID: PANREFERENCEID                                           
          TERMS: VERSION: Terms and condition verification data                           DATE/TIME: Mon, 07 Apr 2014 10:25:217      
   TEXT MESSAGE: $TM*TOKEN NOTIFICATION ADVICE                                                                                       
0 5678901234561234      4234567890123456      11/12/14  15:34:44   T2-TKN DEACTIVATE          VSN     49/12   314316100043288        
     TOKEN DATA: EXP DATE: 16/05   REQUESTOR ID: 45432112345   TYPE: T0   STATUS: I   ASSURANCE LEVEL: 16   REQUEST METHOD: 6        
                 TOKEN REF ID: TOKENREFERENCEDATAID012345678901 PAN REF ID: PANREFERENCEID                                           
          TERMS: VERSION: Terms and condition verification data                           DATE/TIME: Mon, 07 Apr 2014 10:25:217      
   TEXT MESSAGE: $TM*TOKEN NOTIFICATION ADVICE  

В желаемом выводе номер держателя карты и идентификатор запрашивающего лица выводятся в одну строку, например:

1234567890123456,45432112345 
5678901234561234,45432112345

Сейчас у меня есть следующий код, но онне вытягивает подстроку из следующей строки, а вместо строки с номером карты:

$report = get-content $inputFile

foreach ($line in $report) { 
    if ($line -match 'T5-DEVICE PRV RSLT') {
        $card = $line.Substring(2,16)
        $lineRequestor = $line + 1
        $requestorID = $lineRequestor.SubString(49,11)
        if ($card.StartsWith("4")) {
            $card = $card + ','
            $output = $card + $requestorID
            $output | out-file -FilePath $outputFile -Append
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 06 ноября 2019

Следующее упрощенное решение на основе Select-String идентифицирует две части данных для извлечения по количеству содержащихся в них цифр (16 и 11 соответственно).

# Search for lines with cardholder numbers and include one line below
# (-Context 0, 1)
Select-String '\b\d{16}\b' $inputFile -Context 0,1 | ForEach-Object { 
  # Match the requestor ID on the line below.
  $null = $_.Context.PostContext[0] -match '\b\d{11}\b';
  # Output the cardholder number found by Select-String and the
  # requestor ID found with -match
  $_.Matches[0].Value + ',' + $Matches[0] 
} # | Set-Content $outputFile 

Удалите #, чтобы сохранить в $outputFile.

С вашим образцом входного файла это дает:

1234567890123456,45432112345
5678901234561234,45432112345

Что касается того, что вы пытались :

$lineRequestor = $line + 1

Вместо получения следующей строки ввода выполняется объединение строк с текущей строкой и добавление '1' к нему.

Как правило, вы не можете (легко) пропускать перечисление, выполняемое циклом foreach . [1]

Если вы хотите это сделать, используйте цикл for с индексами , как в следующем упрощенном примере:

$lines = 'one', 'two', 'three', 'four'
for ($i = 0; $i -lt $lines.Count; ++$i) {
  # Output a pair of lines.
  "item + next item: " + $lines[$i] + ', ' + $lines[++$i]
}

[1] Технически, вы можете, но решение неясно, через автоматическую $foreach переменную:
foreach ($line in 'one', 'two', 'three', 'four') { $null = $foreach.MoveNext(); $nextLine = $foreach.Current; "$line - $nextLine" }

0 голосов
/ 06 ноября 2019

Предполагая, что записи начинаются с цифры от 0 до 9, за которой следует символ пробела и хотя бы еще одна цифра в первом столбце, вот пример сценария, который может работать для вас:

$inputData = @"
0 CARDHOLDER NUMBER     TOKEN NUMBER          MESSAGE DATE/TIME    ACTIVITY REASON            NTWK   PAN EXP  TRAN ID                
0 1234567890123456      4234567890123456      11/12/14  15:34:38   T1-TKN CREATE              VSN     49/12   314316099993286        
    TOKEN DATA: EXP DATE: 16/05   REQUESTOR ID: 45432112345   TYPE: T0   STATUS: I   ASSURANCE LEVEL: 16   REQUEST METHOD: 6        
                TOKEN REF ID: TOKENREFERENCEDATAID012345678901 PAN REF ID: PANREFERENCEID                                           
          TERMS: VERSION: Terms and condition verification data                           DATE/TIME: Mon, 07 Apr 2014 10:25:217      
  TEXT MESSAGE: $TM*TOKEN NOTIFICATION ADVICE                                                                                       
0 5678901234561234      4234567890123456      11/12/14  15:34:44   T2-TKN DEACTIVATE          VSN     49/12   314316100043288        
    TOKEN DATA: EXP DATE: 16/05   REQUESTOR ID: 45432112346   TYPE: T0   STATUS: I   ASSURANCE LEVEL: 16   REQUEST METHOD: 6        
                TOKEN REF ID: TOKENREFERENCEDATAID012345678901 PAN REF ID: PANREFERENCEID                                           
          TERMS: VERSION: Terms and condition verification data                           DATE/TIME: Mon, 07 Apr 2014 10:25:217      
  TEXT MESSAGE: $TM*TOKEN NOTIFICATION ADVICE                                                                                       
"@ -split [Environment]::NewLine

& {
  foreach ( $row in $inputData ) {
    $outputRow = $false
    if ( $row -match '^\d\s\d+' ) {
      $cardHolderNumber = [Regex]::Match($row,'^\d\s(\d+)').Groups[1].Value
    }
    elseif ( $row -match 'REQUESTOR ID: \d+' ) {
      $requestorID = [Regex]::Match($row,'REQUESTOR ID: (\d+)').Groups[1].Value
      $outputRow = $true
    }
    if ( $outputRow ) {
      [PSCustomObject] @{
        "CardHolderNumber" = $cardHolderNumber
        "RequestorID"      = $requestorID
      }
    }
  }
} | ConvertTo-Csv -NoTypeInformation

Переменная $inputData может быть заменена на Get-Content для чтения входного файла. Вывод приведенного выше сценария:

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