将行转移到列中的更好选择

时间:2016-01-06 01:41:20

标签: powershell

尝试在powershell中堆叠这些列,它可以工作!然而,感觉应该有一个更简单的方法来做到这一点。如果您有替代方案可以实现相同的目标,请告诉我

$lines = @'
5 
b d7 e
c f
'@

$lines = $lines.Split("`n")

$max = $lines | % {$_.trim().split(' ').count} | sort -desc | select -f 1
$count = 0
$obj = New-Object psobject
foreach ($line in $lines) {
    $obj | Add-Member -MemberType NoteProperty -Name $count -Value $line
    $count++
}

for ($x = 0; $x -lt $count; $x++) {
    for ($y = 0; $y -lt $count; $y++) {
        $obj.$y.trim().split(' ')[$x]
    }
}

期望的输出是这样的:

5
b
c
d7
f
e

这是一个更随机的输入和所需输出的例子。脚本:

$alpha = 65..90 | % { [char]$_ }
$lines = for ($i = 0; $i -lt $alpha.Count; $i ++) {
    $line = ''
    $cols = Get-Random -Minimum 1 -Maximum 6
    for ($j = 0; $j -lt $cols; $j++) {
        $line += $alpha[$i+$j] + ' '
    }
    $line.Trim()
    $i = $i + $cols - 1
}

$lines = $lines.Split("`n")

$lines
# Rest of code same as above.

第一部分显示了数组。第二部分显示了我想要它的样子。 (提醒:脚本已经有效,只是寻找替代方案)

A
B C D E
F G
H I
J
K L M N
O
P Q R S
T U V W
X Y Z

A
B
F
H
J
K
O
P
T
X
C
G
I
L
Q
U
Y
D
M
R
V
Z
E
N
S
W

2 个答案:

答案 0 :(得分:1)

$lines=@'
5
b d7 e
c f
'@ -split "`r`n" 

$delimiter=' '
$max=-1
$xform=[ordered]@{}
$lineCount=0

foreach($line in $lines) {    
    $lineCount++
    $key="line$($lineCount)"

    $parts = @($line.trim().split($delimiter))
    $xform.$key = $parts

    if($parts.count -gt $max) {$max=$parts.count}
}

foreach($idx in 0..($max-1)) {    
    foreach($key in $xform.Keys) {
        $xform.$key[$idx]
    }
}

答案 1 :(得分:1)

鉴于$lines是你在上面的字符串之一,这样的东西就可以了。来自文件的文本就像在这里插入一样容易。

$linesArray = $lines -split "`r`n" | ForEach-Object{,($_.Trim() -split '\s')}
$columns = ($linesArray | Measure-Object Count -Maximum).Maximum

$result = for($index =0; $index -lt $columns;$index++){
        $linesArray | Where-Object {$index -lt $_.Length} | ForEach-Object{$_[$index]} | Where-Object{![string]::IsNullOrEmpty($_)}
}

$result包含"转置" arrray。将$lines拆分为行,并将每行拆分为空格(Trim() ed,以防我在示例中找到尾随空格。)

计算最大列数,以便我们知道循环的结构。然后只需按顺序调用每一行的第n个元素。空值被忽略,因此调用非退出元素是一个非问题。

使用PowerShell v4进行测试,但如果需要,可以轻松降级。 $columns是唯一需要改变的东西。

我做了一些修改来解决评论。如果启用了严格模式来标记访问不存在的元素,则简单的where子句将阻止访问那些不存在的元素。解决在后处理问题时返回的空值也是适当的。