1

次の形式のファイルがあります

first:web
last:site
age:99

first:stack
last:overflow
age: 88

私はそれをこのフォーマットに変換しようとしています

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

これまでのところ、すべてを1行で取得するために使用したコードがありますが、ループして分割するための構文を理解できません。

$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 コマンドレットを使用して、「first」で macth を検索し、その行とその後の 2 行を取得できます。

'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

これを処理する方法は複数あります。これが1つです:

$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

別のオプション:

   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 に答える
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 に答える