2017-04-06 11 views
-2

の区切りの発生回数をカウントに基づいて、一列に複数の行をマージ:私はこのようなデータを有する各ライン

 
RE_1|Emp_1|cty_1|analyst_1|end 
RE_2|EMP_2|cty_2|analyst_2|end 
RE_3|EMP_3|cty 
_3|analyst_3|end 
RE_4|EMP_4|cty_4|analyst_4|end 

三行目は2行に分けてしまいました。分割された行を1つにマージする必要があります。すべてのラインに4つのパイプデリメータが必要です。ですから、私は各行に|の数を数える必要があります。それが4であれば、行を印刷します。そうでない場合は、次の行をマージして数をチェックしてください。まだ4でない場合は、次の行もマージします。行に4つの|デリミタが含まれるまで繰り返します。

元のファイルには、10000がこのように分割された何百万もの行が含まれています。ですから、PowerShellやWindowsのバッチでは、これらの行をすばやくマージするためのソリューションが必要です。

答えて

2

あなたは、おそらくこのような正規表現を使用できます。

... -replace '(?ms)^((?:[^\|\r\n]*\|){2}[^\|\r\n]*?)\r?\n((?:[^\|\r\n]*\|){2}end)', '$1$2' 

しかし、私は、メモリ内のレコード数百万のファイルを処理することをお勧めしません。メモリが枯渇したためにコンピュータがスワップを開始した後、コンピュータが停止するまでには本当に楽しいことではありません。

$merged = '' 
Get-Content 'C:\path\to\input.txt' | ForEach-Object { 
    if ($_ -notlike '*|*|*|*|*') { 
    # if the line doesn't have 4 pipe characters in it: append it to the 
    # merged line variable and move on to the next line 
    $merged += $_ 
    } else { 
    # if the line does have 4 pipe characters in it: output and clear the 
    # merged line variable if it contains a value, then output the current 
    # line 
    if ($merged) { 
     $merged 
     $merged = '' 
    } 
    $_ 
    } 
} | Set-Content 'C:\path\to\output.txt' 

# if the input file didn't end with a non-wrapped line the trailing wrapped lines 
# haven't been written to the output file yet 
if ($merged) { 
    $merged | Add-Content 'C:\path\to\output.txt' 
} 
+1

注記私はあなたの知識を尊重していますが、このような質問はなぜクローズする必要がありますか? – Matt

+1

@Matt私は昨日寛大な感覚を持っていたので、OPの努力が不足しているにもかかわらず、他の人にも質問と回答が役に立つと思う。しかも、誰もまだ質問を終わらせないように投票した。 –

関連する問題