PowerShell – Format EDI files and Rename them based on contents

This is an enhancement to a prior blog: PowerShell RegEx Parse EDI. It takes that example to the next step and uses the parsed data to rename the file. It also formats the file by changing the end segment character to the same followed by a carriage-return and line feed.

NOTE: Use this program at your own risk. I suggest making a copy of the files you want to test with, then work on the copy, and improve or tweak this program as needed to customize to your specific needs.

Things you probably need to change:

  1. Obviously the $DirName, and then whether you want to run it recursive or not.
    Or you might want to give an array of directory names, depending how you store and name your files.

  2. It’s currently assuming the files are EDI 850 Purchase Orders, as it is parsing specifically for the BEG segment (BEG03=PONum, BEG0=PO-Date). If you want to handle a wider variety of files, then don’t include these in the file rename. Or add additional logic to parse the files you want to parse and rename.
  3. If you have segment separators other than tilda, you will need about 2-3 lines of code to parse the ISA segment, get the actual separator
  4. Filter – Maybe *.*, *.txt or whatever to match your EDI file names.

You can set this to run as a scheduled task in Windows Task Scheduler. It was written so that you can run the same program over and over on the same directory. Files that get renamed get a double-underscore put in the name. So files that already have a double-underscore can be skipped.

$ErrorActionPreference = "Stop"
$DirName = "c:\EDIClass\ArchiveTest"

$files = Get-ChildItem $Dirname -Recurse -Filter *.edi  
foreach ($file in $files) 

    $fullname = $file.FullName.ToString();  
    $dirname = $file.Directory.ToString(); 
    $filename = $file.Name.ToString(); 

    $posTwoUnderScores = $filename.IndexOf("__") 
    if ($posTwoUnderScores -lt 0) 

        Write-Host "OldName $fullname"
        $content = Get-Content $file.FullName

        Write-Host "RowCount=$($content.Count)"

        if ($content.Count -le 1) ## more than one line in file 
           # break the file into separate lines, 
           # but save the date/times and restore them 
           # after we update the file 
           $origCreationTime  =  $file.CreationTime
           $origLastWriteTime =  $file.LastWriteTime
           Write-Host "Creation    Time: origCreationTime"
           Write-Host "Last Write  Time: origLastWriteTime"

           $content = $content.Replace("~","~`r`n")
           set-content $fullname $content 
           (Get-ChildItem $file.FullName).CreationTime = $origCreationTime
           (Get-ChildItem $file.FullName).LastWriteTime = $origLastWriteTime

        $CompanyID  = [regex]::match($content,'.*ISA\*.*?\*.*?\*.*?\*.*?\*.*?\*(.*?)\*.*').Groups[1].Value
        $CompanyID  = $CompanyID.Trim()
        $ControlNum = [regex]::match($content,'.*ISA\*.*?\*.*?\*.*?\*.*?\*.*?\*.*?\*.*?\*.*?\*.*?\*.*?\*.*?\*.*?\*(.*?)\*.*').Groups[1].Value
        $OrderNum   = [regex]::match($content,'.*BEG\*.*?\*.*?\*(.*?)\*.*').Groups[1].Value
        $OrderDate  = [regex]::match($content,'.*BEG\*.*?\*.*?\*.*?\*.*?\*(.*?)[~\*].*').Groups[1].Value
        $EdiDocType = [regex]::match($content,'.~ST\*(.*?)[~\*].*').Groups[1].Value
        Write-Host "$OrderNum $OrderDate EdiDocType $CompanyID $ControlNum"

        Write-Host "Filename=$filename"
        $newFileName = $dirname + "\" + $CompanyID + "_" + $EdiDocType + "__" + $OrderNum + "_" + $OrderDate  + "_" + $filename
        Write-Host "NewName $newFileName`n" 
        Rename-Item $fullname $newFileName 
    } #end test for if file contains two underscores already 
} #end for-each loop


Leave a Reply