2013-06-21 1 views
2

일련의 로그 파일에서 "오류"패턴을 검색하고 그 결과를 텍스트 파일에 쓰려고합니다.PowerShell : 로그 파일에서 문자열의 일부 검색

나는 명령을 사용하고 있습니다 :

foreach($file in $files){ 

    $match = get-content $file | Select-String $p | Out-File $matchfile 
} 

패턴 $ (P)는 명령 줄에서 촬영되었습니다. Windows Server 2008 R2에서 스크립트를 실행하고 있으며 "오류"가 로그 파일의 한 단어 인 경우 결과를 반환합니다. 스크립트에서 식별 할 수 있도록 "ErrorCode"인스턴스가 있습니다.

나는 원하는대로 Windows 7에서 작동하는 코드를 가지고 있습니다. 그러나 Windows Server 2008 R2에서 스크립트를 실행할 때 결과가 나타나지 않습니다. PowerShell 버전은 모두 2.0입니다.

+0

패턴 "Error"는 Error 및 ErrorCode와 일치해야합니다. 정확히 사용 된 패턴은 무엇입니까? – zdan

답변

2

Windows 7에서 실제로 작동하는지 확인 하시겠습니까? 당신이 작성한대로, foreach 루프를 반복 할 때마다 매치 파일을 $ files의 마지막 파일의 결과로 덮어 씁니다. Out-File 다음에 -Append 스위치를 추가 할 수 있지만 foreach 루프가 필요하지 않습니다. 또한 $ match의 목적은 무엇입니까? $match =은 나에게 불필요 해 보입니다. 이 시도 :

Get-Content $files | Select-String $p | Out-File $matchfile 

나는 당신이 2K8 서버의 모든 결과를 얻지 못하고있는 이유는 $ 파일의 마지막 파일이 $ 피에 대한 일치가이 없다는 것을 생각한다. Windows 7 컴퓨터에서는 마지막 파일에 $ p와 일치하지만 다른 파일에서 결과를 얻지 못하기 때문에 결과가 나타납니다.

+0

Windows 7에서 작동하고 있다고 생각한 이유는 마지막 로그 파일에 패턴이 포함되어 있기 때문입니다. 분명히 그것은 옳지 않았고, 나는 조금 천천히 움직였습니다. 고마워요! :) – user2509413

0

두 번째 @Adi, 각 반복에서 파일을 덮어 쓰고 있습니다. 추가 스위치를 Out-File에 추가하여이 문제를 해결할 수 있습니다. 이것은 또한 작동하고 더 간단해야한다 :

$files | Select-String $p | Out-File $matchfiles 
0

$ match는 항상 null이 될 것이라고 기대한다. 도움에 따르면 Out-File은 파이프 라인을 통해 아무 것도 전송하지 않습니다. 그러나 그것이 당신의 문제와 관련된 것이라면 나는 놀랄 것이다. 의 정신


내가 Win7에와 WS08R2 모두에서 간단한 실험을 시도하고 결과를 repro 수 없습니다 ... "어떤 도움도 대단히 감사하겠습니다"(예상대로 일했다). 또한 다른 인코딩으로 검색되는 파일을 만들려고했는데 유니 코드, UTF8 및 ASCII입니다. 모두 일했습니다. 나는 심지어 Select-String에 잘못된 인코딩을 사용하라고 말하기까지했다.

get-content mytestfile.ascii | select-string error -Encoding Unicode 

그리고 여전히 효과가있다. mytestfile.ascii, mytestfile.unicode 및 mytestfile.utf8이 실제로 다르게 인코딩되었는지 확인하기 위해 16 진수 뷰어를 사용했습니다. 나는 또한 다른 라인 엔딩 (리눅스 스타일 대 윈도우 스타일)을 시도해 보았다.

내 생각에 당신은 파일, 시스템 등에 대해 뭔가 탐구를 통해 발견 되어야만하는 독특한 점이 있다고 생각합니다. 그걸 염두에두고 ...


으로 난 당신이 헥스 뷰어 (두 시스템에서 그것을 시도) 무언가가 당신의 Win7에 시스템과 WS08R2 시스템 간의 차이가 있는지 확인하기 위해 귀하의 로그 파일 중 하나 내부를 들여다 좋습니다. UTF8 파일의 시작 부분에 EF BB BF가 표시되고 로그의 각 문자에 대해 1 바이트가 표시됩니다. 유니 코드 파일의 시작 부분에 FF FE와 모든 문자에 대해 2 바이트가 표시됩니다. (텍스트가 영어이면 다른 모든 문자는 0이됩니다.ASCII 파일의 경우 시작 부분에 특별한 값이 없으며 글자 당 1 바이트가 있습니다. 리눅스 줄 끝은 단일 0A (줄 바꿈)이고 Windows 줄 끝은 0D 0A (캐리지 리턴, 줄 바꿈)입니다. 위에서 언급 한 바와 같이 처음에는 특수 문자와 줄 끝을 제외하고 텍스트를 메모장에서 본 것과 똑같은 문자 집합을 찾고 있습니다. (BTW, 메모장에서 보는 것은 줄 끝이 Windows 스타일 인 경우에만 "오른쪽"으로 보입니다). 여분의 문자가 있으면 문제의 원인이 될 수 있습니다.

예기치 않은 결과가 표시되지 않으면 Powershell 명령 줄에서 일련의 실험을 제안합니다. 다음 절차에는 많은 단계가 나열되어 있지만 많은 우발적 인 사건을 다루려고합니다. 모든 단계를 수행하지 않을 것입니다. (그러나 초기 몇 가지 수정을 통해 테스트 할 로그 파일에 "오류"가 나타나는 위치를 설명하기 위해이 전체 스크립트를 복사하여 붙여 넣은 다음 한 번에 전체 결과 집합을 해석 할 수 있습니다)

# 0. Get some text to experiment with 
# If "error" appears on line 200 and line 493 (where first line in file is Line 1), then: 
$testTxt= cat mylogfile | select-object -skip 195 -first 300 
# or better still: 
$testTxt= cat mylogfile | select-object -skip 195 -first 10 
$testTxt2= cat mylogfile | select-object -skip 488 -first 10 
$testTxt += $testTxt 

# 1. Figure out where in testTxt "error" appears 
$testTxt[3..5] # if my math is right "error" will appear as middle line 

# 2. If #1 doesn't work on both systems, then on failing system(s): 
$testTxt[4] | select-string error 

# 2.5 If #2 fails then you need to look at every character 
# of $testTxt 
[char[]]$testTxt 
# or even look at every byte value in hex: 
[byte[]][char[]]$textTxt | % { $_.tostring("X")} 

# 3. If #2 worked, then: 
$testTxt | select-string error 

# 4. If #3 failed, then: 
$testTxt[3..5] | select-string error 

# 5. If #4 failed, then: 
$testTxt[3..4] | select-string error 
$testTxt[4..5] | select-string error 

# 6. If either of #5 failed, then carefully examine those lines of text: 
"line 3" 
[char[]]$testTxt[3] 
"line 4" 
[char[]]$testTxt[4] 
"line 5" 
[char[]]$testTxt[5] 

# 7. If #3 worked then: 
$testTxt2 = cat myLogFile 
$testTxt2 | select-string error 

# 8. If #7 worked, then you have a solution 
# Replace: 
get-content $file | Select-String $p | Out-File $matchfile 
# With (on Powershell v3 this may perform worse than the above, assuming above worked) 
$logText = get-content $file 
$logText | Select-String $p | Out-File $matchfile 

# 9. If #8 failed, then the situation is somewhat awkward. 
# On one hand you have twenty lines working, but on the other the file as a whole 
# doesn't work. You could go back to step #0 and start with a larger amount of text, 
# say 40 lines, and see if it works. If it does you could try 80, 160, etc. until it 
# fails. But this case seems pretty unlikely. 

# 10. In general when a step fails you want to try something "smaller". And when steps 
#  succeed you want to try something "bigger", where "bigger" means more like the 
#  solution you want.