[英]Powershell fixed width export
我有一个文本文件,它使用固定的宽度分隔列。
我正在加载文件并创建一个新列,该列隐含了前两列的值。 我的问题是,导出数据时,我需要为列C定义固定的列宽13。
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
}
提前致谢
您可以使用此处说明的技巧创建自定义表格格式。 这是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
。 您无需构建自己的每一行格式,而是构建一个哈希并将其通过Format-Table传递。
对我来说仍然不清楚您实际上想要实现什么输出,但是也许这会给您一些想法。
获得格式化字符串输出的最便捷方法之一是使用格式运算符 ( -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 _
您可以使用以下代码快速获得固定大小的左对齐内容字符串:
写主机“ $ myvariable $(”“ * 60)”。Substring(0,60)
这将为您提供60个字符的固定宽度,内容向左对齐
一种解决方案是,对于每个行,在连接时使用此机制:
$a = "MMA"
$b = "12345"
$str = "$($b)_$($a)"
if (($str.Length) -ge 13 ) {
Write-Host "$($str)"
} else {
$padStr = " " * (13 - ($str.Length))
Write-Host "$($str)$($padStr)"
}
因此,您可以使用合适的CmdLet代替Write-Host 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]
}
您可以使用以下代码进行固定大小的操作:
$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.