1

我有一个格式为

first:web
last:site
age:99

first:stack
last:overflow
age: 88

我正在尝试将其转换为这种格式

first|last|age
web|site|99
stack|overflow|88

到目前为止,这是我用来在一行中获取所有内容的代码,但我无法弄清楚循环遍历它并打破它的语法

$TextLocation = "data.txt" 
$Writefile =  "results.txt" 
$FileLocation = "C:\Users\"
$SearchStr1 = "First:"
$SearchStr2 = "Last:"
$SearchStr3 = "Age:"
$SearchStr4 = ""


#Get content
$a =Get-Content $TextLocation  |

#Find search strings and replace with pipes

Foreach-Object {
    $_  -replace $SearchStr1 , "|" `
    -replace $SearchStr2, "|" `
    -replace $SearchStr3, "|" `
    -replace$SearchStr4, "|" `

} |

# join all lines
$a -join "" 

#Break after every 4th pipe

谢谢

4

4 回答 4

4

您可以使用 Select-String cmdlet 在“first”上查找 macth 并获取该行以及后面的两行:

'first|last|age'

Get-ChildItem .\file.txt | Select-String '^first:' -Context 0,2 | ForEach-Object{

    $f = $_.Line.Split(':')
    $l = $_.Context.PostContext[0].Split(':')
    $a = $_.Context.PostContext[1].Split(':')

    $f[1],$l[1],$a[1] -join '|'

}

first|last|age
web|site|99
stack|overflow| 88
于 2012-08-30T19:37:21.547 回答
0

将有多种方法来处理这个问题。这是一个:

$result = @()
$temp = New-Object PSCustomObject -Prop @{'first' = ''; 'last' = ''; 'age' = ''}
foreach($line in Get-Content C:\PATH\TO\INPUT.txt){
    if($line.StartsWith('first')){
        $temp.first = $line.Split(':')[1]
    }elseif($line.StartsWith('last')){
        $temp.last = $line.Split(':')[1]
    }elseif($line.StartsWith('age')){
        $temp.age = $line.Split(':')[1]
    }else{
        $result += $temp
        $temp = New-Object PSCustomObject -Prop @{'first' = ''; 'last' = ''; 'age' = ''}
    }
}
$result += $temp
$result | Export-CSV C:\PATH\TO\RESULT.csv -NoTypeInformation -NoHeader -Delimiter '|'

这不是我真正会做的,但它是骨架,应该让你开始。至少,您可能希望确保它更好地处理文件中的第一条和最后一条记录。我只是以这种方式将它拍打在一起作为演示。

于 2012-08-30T19:04:20.510 回答
0

这是一个相当通用的解决方案:

$contents = gc C:\test.txt
$printedHeader = $false;
for ($i=0; $i -lt $contents.Length; $i++){
    $line = $contents[$i];
    $keyVal = $line.Split(':',2)
    $keys += $keyVal[0];
    $vals += $keyVal[1];    

    if ($contents[$i] -eq "" -or $i -eq $contents.Length - 1){
        if ($printedHeader -eq $false){
            $keys -join "|"
            $printedHeader = $true;
        }       
        $vals -join "|"     
        $vals = @();
        $keys = @();        
    }   
}
于 2012-08-30T19:20:16.717 回答
0

另外一个选项:

   function Get-Data($Path='c:\data') {

      $content = (Get-Content $Path | where {$_}) -split ':'
      for($i=0;$i -lt $content.length;$i++) {
          if(!$i) { 'first|last|age' }
          if($i % 2 -eq 1) {
               $content[$i],$content[$i+2],$content[$i+4] -join '|'
               $i+=5
           }
       }
    }

    PS II> Get-Data c:\scripts\data.txt

    first|last|age
    web|site|99
    stack|overflow| 88
于 2012-09-01T11:34:10.517 回答