简体   繁体   English

Powershell固定宽度导出

[英]Powershell fixed width export

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. 我的问题是,导出数据时,我需要为列C定义固定的列宽13。

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. 基本上对于导出中的此示例,我在第一行缺少4个空格,在第二行缺少3个空格。

Thisis my current code, which also includes a new row for MD5 creation. 这是我当前的代码,其中还包括用于创建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

}

Thanks in advance 提前致谢

You can create a custom table format using the tip explained here . 您可以使用此处说明的技巧创建自定义表格格式。 Here is an example for Get-Process : 这是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. 基本上,您可以通过Format-Table构建一个表达式,该表达式将对每行进行管道Format-Table Instead of taking care of the formating yourself for each row, you build a hash and pipe it through Format-Table. 您无需构建自己的每一行格式,而是构建一个哈希并将其通过Format-Table传递。

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 ). 获得格式化字符串输出的最便捷方法之一是使用格式运算符-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, eg with the Substring() method: 如果某个值对于给定列宽度而言过长,则需要截断它,例如,使用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      _

You can quickly have a fixed size left-aligned content string using the following code: 您可以使用以下代码快速获得固定大小的左对齐内容字符串:

Write-Host "$myvariable $(" " * 60)".Substring(0,60) 写主机“ $ myvariable $(”“ * 60)”。Substring(0,60)

this will give you a fixed width of 60 characters with the contents aligned to the left 这将为您提供60个字符的固定宽度,内容向左对齐

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. 因此,您可以使用合适的CmdLet代替Write-Host CmdLet。

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]

} 

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 ''

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM