3

I am having a text file wich uses fixed width for separating columns.

I'm loading the file and create a new column which concatinates the values of the first two columns. The problem I have that when exporting the data I need to define a fixed column width of 13 for Column C.

Column A (3)   Column B(9)   Column C(13)
MMA            12345         12345_MMA
MMO            987222        987222_MMO

Basically for this example in the export I am missing 4 spaces for the first row and 3 for the second row.

Thisis my current code, which also includes a new row for MD5 creation.

    # Load input data
$PreSystem = [IO.File]::ReadAllText("C:\FILE.txt")

# Initiate md5-hashing
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$utf8 = new-object -TypeName System.Text.UTF8Encoding

# Split input data by lines
$all = $PreSystem.split("`n") 

# Loop over lines
for($i = 0; $i -lt $all.length-1; $i += 1) {
  # Access distinct lines
  $entry = "$($all[$i])"
  # Get the different parameters
  $market_code = $entry.substring(1,3)
  $soc = $entry.substring(4,9)
  # Hash the SOC element
  $hash = [System.BitConverter]::ToString($md5.ComputeHash($utf8.GetBytes($soc)))
  # Create desired format for each entry
  $output = $hash.Replace("-","")+$soc.Replace(" ","") + "_" + $market_code + $all[$i]
  # Write to file
  "$output" | Out-File -Filepath C:\"C:\FILE.txt" -Append -encoding ASCII

}

Thanks in advance

user2428207
  • 825
  • 4
  • 16
  • 29

5 Answers5

4

It's still not quite clear to me what output you actually want to achieve, but maybe this will give you some idea.

One of the most convenient ways to get formatted string output is using the format operator (-f). You specify a format string with placeholders in curly brackets, and fill it with the values of an array:

PS C:\> '_{0}:{1}:{2}_' -f 'foo', 'bar', 'baz'
_foo:bar:baz_

Column widths can be specified in the format string like this:

PS C:\> '_{0,-5}:{1,7}:{2,-9}_' -f 'foo', 'bar', 'baz'
_foo  :    bar:baz      _

As you can see, negative values align the column to the left, positive values align it to the right.

If there's a chance that a value is too long for the give column width you need to truncate it, e.g. with the Substring() method:

PS C:\> $s = 'barbarbar'
PS C:\> $len = [math]::Min(7, $s.Length)
PS C:\> '_{0,-5}:{1,7}:{2,-9}_' -f 'foo', $s.Substring(0, $len), 'baz'
_foo  :barbarb:baz      _
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
3

You can create a custom table format using the tip explained here. Here is an example for Get-Process:

$a = @{Expression={$_.Name};Label="Process Name";width=25}, `
@{Expression={$_.ID};Label="Process ID";width=15}, `
@{Expression={$_.MainWindowTitle};Label="Window Title";width=40}

Get-Process | Format-Table $a

Basically, you build an expression through wich Format-Table will pipe each row. Instead of taking care of the formating yourself for each row, you build a hash and pipe it through Format-Table.

Thom A
  • 88,727
  • 11
  • 45
  • 75
David Brabant
  • 41,623
  • 16
  • 83
  • 111
1

You can quickly have a fixed size left-aligned content string using the following code:

Write-Host "$myvariable $(" " * 60)".Substring(0,60)

this will give you a fixed width of 60 characters with the contents aligned to the left

0

One of the solutions is for each of the rows use this mechanism when concatenating:

$a = "MMA"
$b = "12345"

$str = "$($b)_$($a)"

if (($str.Length) -ge 13 ) {
    Write-Host "$($str)"
} else {
    $padStr = " " * (13 - ($str.Length))
    Write-Host  "$($str)$($padStr)"
} 

So instead of Write-Host CmdLet you can use the appropriate CmdLet for your purpose.

Edit, after adding actual code. So the above logic would translate into:

$market_code = $entry.subString(1,3)
$soc = $entry.subString(4,9)

$str = $soc.Replace(" ", "") + "_" + $market_code

if (($str.Length) -ge 13 ) {
    $output = $hash.Replace("-","") + $str + $all[$i]
} else {
    $padStr = " " * (13 - ($str.Length))
    $output = $hash.Replace("-","") + $str + $padStr + $all[$i]

} 
Eduard Uta
  • 2,477
  • 5
  • 26
  • 36
0

You can do fixed size using next code:

$data = "Some text"
$size = 20
$str = [string]::new(' ',$size).ToCharArray()
$data.CopyTo(0,$str,0,$data.Length)
$str = $str -join ''