2017-04-06 2 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 

세 번째 라인은 두 개의 행으로 분할되었다합니다. 분할 선을 하나로 병합해야합니다. 모든 라인에는 4 개의 파이프 분리 계가 있어야합니다. 그래서 각 줄에 |의 수를 세어야합니다. 그것이 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의 노력이 부족함에도 불구하고 질문과 대답이 다른 사람들에게도 유용 할 수 있다고 생각합니다. 게다가 아무도이 질문을 아직 끝내지 않기로 결정했습니다. –

관련 문제