Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

How can I modify this Powershell script to only look for the first N3 and N4 segment?

Posted on 2014-10-21
2
86 Views
Last Modified: 2014-10-22
I would like to modify the following script:

$InputFile = "C:\Data\Original.txt"
$OutputFile = "C:\Data\New.txt"

 Function ParseText ($OutputFile,$InputFile){
 Begin{
             $line,$poline,$shipto,$totline,$total,$i,$n3 = $null,$null,$null,$null,$null,0,0
             Set-Content $OutputFile $null
             $Data = Get-Content -Path $InputFile | ?{$_ -match "(G50\*)|(G69\*)|(G68\*)|(N\d\*)|(IEA\*)"}
       }
 Process{
       $Data | % {
       #Check the end of data set
             If ($_ -match "IEA\*"){
                   If($poline -ne $null -and $total -ne $null){
                         $Totline = "Total: `$$Total"
                         Write-host "This is Total `$$total"
                         #Write the data collection to output file
                         "$poline$shipto$line`r`n$totline`r`n" | out-file $OutputFile -Encoding UTF8 -Append
                         #reset the variables
                         $line,$poline,$shipto,$totline,$total,$i,$n3 = $null,$null,$null,$null,$null,0,0
                   }
             }
             #Collect the PO Number
             If($_ -match "G50\*" -and $_ -match "(\w{2}\*)(\d{3,10})"){
                   $poline = "PO Number: $($Matches[2])"
             }
             #Collect the Ship To information
             If($_ -match "(N3\*)([^*~]+)"){
                   $n3++
                   If($n3 -eq 2){
                         $shipto = "`r`nShip to: $($Matches[2])"
                   }
             }
             If($n3 -eq 2 -and $shipto -ne $null -and $_ -match "(N4\*)([^*~]+)"){
                   $shipto = "$shipto, $($Matches[2])"
             }               
             #Collect  G68 details and following G69 Description
             If($_ -match "(G68\*{1,})(\d{1,})\*(\w{1,})\*(\d{1,}(\.\d{1,})?)\*{1,}(\w{1,}|\d{1,})"){
                   $i++
                   $total += [double]$Matches[2] * [double]$Matches[4]
                   $Desc = ($Data[([Array]::IndexOf($Data,$_)+1)] -split "\*{1,}|~")[1]
                   [String[]]$line += "`r`nItem $i`: UPC: $($Matches[6]), Desc: $Desc, Qty: $($Matches[2]), Price: `$$($Matches[4])"
             }
       }
  }
  }
 If(Test-Path $InputFile){
  ParseText $OutputFile $InputFile
 }

Open in new window


My focus is on the N3 and N4 segment.
At the moment, with the script as is, will look at the 2nd instance it finds of the N3 and N4, which is good.
However, if there is a 3rd instance of N4, it will also show that as well.  I don't want the script to look for a 3rd instance of a line starting with N4.  If it finds a 3rd instance of a line that starts with N4, it must not do anything with it.
0
Comment
Question by:100questions
2 Comments
 
LVL 35

Accepted Solution

by:
Robert Schutt earned 500 total points
ID: 40396299
Do you have an example document where this happens? I have constructed a document where the problem happens and solved it with the code below but I felt unsure if I could reproduce the problem with a valid document. An N4 can normally only be used right after an N3, right? If not then the check must be changed, actually it would be better anyway to check for N1 records and the type (BT/ST etc) instead of counting N3 records. I must admit though that my ANSI X12 knowledge is a bit rusty...

Anyway, here is the code:
 Function ParseText ($OutputFile,$InputFile){
 Begin{
             $line,$poline,$shipto,$totline,$total,$i,$n3,$n4 = $null,$null,$null,$null,$null,0,0,0
             Set-Content $OutputFile $null
             $Data = Get-Content -Path $InputFile | ?{$_ -match "(G50\*)|(G69\*)|(G68\*)|(N\d\*)|(IEA\*)"}
       }
 Process{
       $Data | % {
       #Check the end of data set
             If ($_ -match "IEA\*"){
                   If($poline -ne $null -and $total -ne $null){
                         $Totline = "Total: `$$Total"
                         Write-host "This is Total `$$total"
                         #Write the data collection to output file
                         "$poline$shipto$line`r`n$totline`r`n" | out-file $OutputFile -Encoding UTF8 -Append
                         #reset the variables
                         $line,$poline,$shipto,$totline,$total,$i,$n3,$n4 = $null,$null,$null,$null,$null,0,0,0
                   }
             }
             #Collect the PO Number
             If($_ -match "G50\*" -and $_ -match "(\w{2}\*)(\d{3,10})"){
                   $poline = "PO Number: $($Matches[2])"
             }
             #Collect the Ship To information
             If($_ -match "(N3\*)([^*~]+)"){
                   $n3++
                   $n4 = 0 # restart N4 counter after finding N3
                   If($n3 -eq 2){
                         $shipto = "`r`nShip to: $($Matches[2])"
                   }
             }
             If($n3 -eq 2 -and $shipto -ne $null -and $_ -match "(N4\*)([^*~]+)"){
                   $n4++
                   If($n4 -eq 1){ # only the first N4 under a N3
                         $shipto = "$shipto, $($Matches[2])"
                   }
             }               
             #Collect  G68 details and following G69 Description
             If($_ -match "(G68\*{1,})(\d{1,})\*(\w{1,})\*(\d{1,}(\.\d{1,})?)\*{1,}(\w{1,}|\d{1,})"){
                   $i++
                   $total += [double]$Matches[2] * [double]$Matches[4]
                   $Desc = ($Data[([Array]::IndexOf($Data,$_)+1)] -split "\*{1,}|~")[1]
                   [String[]]$line += "`r`nItem $i`: UPC: $($Matches[6]), Desc: $Desc, Qty: $($Matches[2]), Price: `$$($Matches[4])"
             }
       }
  }
  }
 If(Test-Path $InputFile){
  ParseText $OutputFile $InputFile
 }

Open in new window

tested by putting this in the document:
  N1*SU*Company*8*123456789~
  N1*BT*Name*8*1234567891234~
  N3*1 Company~
  N4*LOC*BB*ABC  DEF*CA~
  N1*ST*D021 Loc*9*1234567891236~
  N3*Street~
  N4*Location*BB*ABC DEF*CA~
  N1*XX*D021 Loc2*9*1234567891236~
  N4*Location2*BB*ABC DEF*CA~

Open in new window

old output:
PO Number: 8888888887
Ship to: Street, Location, Location2
Item 1: UPC: UK, Desc: 1, Qty: 10, Price: $12
Total: $120

PO Number: 8888888891
Item 1: UPC: UK, Desc: 1, Qty: 2, Price: $40.10
Total: $80.2

Open in new window

new output:
PO Number: 8888888887
Ship to: Street, Location
Item 1: UPC: UK, Desc: 1, Qty: 10, Price: $12
Total: $120

PO Number: 8888888891
Item 1: UPC: UK, Desc: 1, Qty: 2, Price: $40.10
Total: $80.2

Open in new window

I'm not sure if the rest of the output is ok because I only had an old input document (this code uses G50/G68 instead of SA/PO1) but the code change itself should be usable in either version.

By the way, regarding that remark I made earlier about checking N1 records instead of counting N3 records: I was testing a bit of code but haven't made it into a working script yet. This could be changed to account for optional/multiple N2/3/4 records. It goes something like this:
             #Collect the Ship To information
             If($_ -match "(N1\*)(\w+)(\*)"){
                   $ntype = $Matches[2]
             }
             If($_ -match "(N3\*)([^*~]+)"){
                   If($ntype -eq "ST"){
                         $shipto = "`r`nShip to: $($Matches[2])"
                   }
             }
             If($_ -match "(N4\*)([^*~]+)"){
                   If($ntype -eq "ST" -and $shipto -ne $null){
                         $shipto = "$shipto, $($Matches[2])"
                   }
             }               

Open in new window

0
 

Author Closing Comment

by:100questions
ID: 40397059
Excellent work, thanks.
0

Featured Post

NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Power shell script 2 30
Tricky powershell this time 4 23
PowerShell Move Folders and Files 3 10
Nested ForEach in Powershell 4 13
How to sign a powershell script so you can prevent tampering, and only allow users to run authorised Powershell scripts
The Nano Server Image Builder helps you create a custom Nano Server image and bootable USB media with the aid of a graphical interface. Based on the inputs you provide, it generates images for deployment and creates reusable PowerShell scripts that …
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

791 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question