Category Archives: String parsing

Position map a string with Powershell

I was parsing some text data, and was trying to count character postions in a string displayed in the console.

Decided there had to be a better way, so I wrote this filter to position map a string.

filter write-positionmap {
$ofs = ""

$positions = 0..($_.length -1) | foreach {"{0:0####}" -f $_}
$part_count = [math]::truncate($_.length / 100)

foreach ($part in 0..$part_count){
    if ($_.length -ge ($part * 100)){$end = 99}
    else {$end = $_ % 100}
$part_positions = $positions[($part * 100)..($part * 100 + $end)]
write-output $([string]$_[($part * 100)..($part * 100 + $end)])
write-output $([string]($part_positions | % {$_.tostring()[-1]}))

if ($end -gt 9){
    $position_line = @()
    $part_positions |% {
        if ([int][string]$_[-1]){$position_line += " "}
        else {$position_line += [string]$_[-2]}
        }
  write-output $([string]$position_line)
  }

  if ($part -ge 1){
    $position_line = @()
    $part_positions |% {
        if ([int][string]$_[-1]){$position_line += " "}
        else {$position_line += [string]$_[-3]}
        }
  write-output $([string]$position_line)
  }

  if ($part -ge 10){
    $position_line = @()
    $part_positions |% {
        if ([int][string]$_[-1]){$position_line += " "}
        else {$position_line += [string]$_[-4]}
        }
  write-output $([string]$position_line)
  }
 write-output " "
 }

}

Should work on any string up to 10,000 characters.

Update:

In response to a rquest to an description of it’s application, I’ll use an example form this post by Doug Finke

http://www.dougfinke.com/blog/index.php/2011/08/31/choosing-an-approach/

It creates custom PS objects from undelimited positional data, using a series of substring operations. This is a good approach, but the process of finding where each column begins and ends to write the substring arguments can be tedious. Using the write-positionmap filter on the column header line of the file make it easier to determine where each column begins and how many characters it has:

PS C:\testfiles> (get-content testdata.txt)[2] | write-positionmap