Экспорт фиксированной ширины Powershell

У меня есть текстовый файл, который использует фиксированную ширину для разделения столбцов.

Я загружаю файл и создаю новый столбец, который объединяет значения первых двух столбцов. У меня проблема в том, что при экспорте данных мне нужно определить фиксированную ширину столбца 13 для столбца C.

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

В основном для этого примера в экспорте мне не хватает 4 пробелов для первой строки и 3 для второй строки.

Это мой текущий код, который также включает новую строку для создания MD5.

    # 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

}

заранее спасибо


person user2428207    schedule 15.01.2015    source источник
comment
Пожалуйста, покажите свой код. Также может быть полезен пример фактического и желаемого результата.   -  person Ansgar Wiechers    schedule 15.01.2015


Ответы (5)


Вы можете создать собственный формат таблицы, используя совет, описанный здесь. Вот пример для 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

По сути, вы строите выражение, через которое Format-Table будет передавать каждую строку. Вместо того, чтобы самостоятельно форматировать каждую строку, вы создаете хэш и передаете его через Format-Table.

person David Brabant    schedule 15.01.2015

Мне все еще не совсем ясно, какого результата вы на самом деле хотите достичь, но, возможно, это даст вам некоторое представление.

Один из самых удобных способов получить отформатированный строковый вывод — использовать оператор формата (-f). Вы указываете строку формата с заполнителями в фигурных скобках и заполняете ее значениями массива:

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

Ширину столбцов можно указать в строке формата следующим образом:

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

Как видите, отрицательные значения выравнивают столбец по левому краю, положительные значения выравнивают его по правому краю.

Если есть вероятность, что значение слишком длинное для заданной ширины столбца, вам нужно его обрезать, например. методом Substring():

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      _
person Ansgar Wiechers    schedule 15.01.2015

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

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

это даст вам фиксированную ширину 60 символов с содержимым, выровненным по левому краю

person Filipe Camizao Lage    schedule 30.06.2017
comment
Простой, но элегантный. - person Aaron C; 14.05.2019

Одно из решений заключается в том, что для каждой из строк используется этот механизм при объединении:

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

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

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

Таким образом, вместо Write-Host CmdLet вы можете использовать соответствующий CmdLet для своих целей.

Отредактируйте после добавления фактического кода. Таким образом, приведенная выше логика будет переведена на:

$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]

} 
person Eduard Uta    schedule 15.01.2015

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

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