
직장 시스템 어딘가에서 사라진 파일 목록이 있습니다. 또한 누락된 파일과 관련된 로그 항목이 있는 최대 46MB의 로그 파일 41개로 가득 찬 폴더도 있습니다. 내 목록의 값에 대해 이러한 로그 파일을 어떻게 찾을 수 있습니까?
목록은 파일 확장자 없이 한 줄에 하나의 파일로 구성됩니다. 로그에는 구조가 있는 것 같지만 아직 그 구조에 완전히 익숙하지는 않습니다. 여기에는 파일 이름과 경로는 물론 파일에 수행된 작업도 포함되어 있습니다.
cat *
모든 로그 파일을 파이프라인으로 보낼 수 있다는 것을 알고 있습니다 grep
. 이름이 발견되면 로그 파일에서 약간의 컨텍스트를 얻기 위해 -A
및 를 사용할 것입니다 . -B
Windows에서 GnuWin32를 사용하고 있으므로 이것을 Powershell과 결합할 수 있지만 그렇게 하려면 하나의 파일 이름이 46MB를 모두 잡아야 하고 다음 파일 이름으로 이동할 때 다시 시작해야 한다고 생각합니다. 목록에 1830개의 파일이 있으므로 각 파일을 새로 시작해야 한다면 결국 46MB를 너무 많이 읽게 되어 GB 단위의 반복 데이터를 처리하게 됩니다. 그렇게 하는 것은 비효율적일 것 같습니다.
1830개 파일의 대규모 정규 표현식을 함께 작성하고 로그에 대해 한 번 실행할 수 있다고 생각하지만 그게 가능할까요? 정규식은 거의 30KB입니다(1830개 파일 * 약 16자의 파일 이름 평균 길이 = 29280바이트, 또 다른 1830바이트의 파이프 기호는 말할 것도 없음).
편집하다:로그 폴더에 있고 목록이 한 폴더 뒤에 있을 때 지금 수행 중인 작업은 다음과 같습니다.
$logs = gc *
$notfound = gc ../notfound.txt
$logs | % { $i = 0; while ($i -lt $notfound.Count) { if ($_ -contains $notfound[$i]) { echo $_ }; $i++; } } | out-file C:\discovered.txt
그것은 완전히 파워쉘이다. 현재 결합된 모든 로그 파일에 550991줄이 있고 1830개의 파일 이름이 있으므로 이 접근 방식을 사용하면 속도를 높이기 위해 어떤 도구든 사용할 수 있습니다.1,008,313,530개 비교. 모두 메모리에 있으므로 적어도 디스크 I/O로 인해 속도가 느려지지는 않습니다. while
만약 이것이 사실이 된다면 그 상황에서 벗어날 수 있을지도 if
모르지만, 여전히 너무 많은 비교를 할 것이기 때문에 최적화가 실제로 어떤 좋은 결과를 가져올지는 잘 모르겠습니다. 벌써 30분 동안 실행되고 있습니다. 주말에 집에 가기 전에 완료할 수 있다면 라인 1의 접근 방식을 다시 작성해도 괜찮습니다.
답변1
정규식을 통해 로그에서 파일 이름을 꺼내어 각 파일 이름이 목록에 있는지 확인하는 것이 더 효율적입니다. 다음과 같이 보일 수 있습니다.
$notfound = gc ../notfound.txt
gc * |
select-string -AllMatches '\\(?<filename>[^\\]+)\.txt' |
select -ExpandProperty Matches |
% { $_.Groups['filename'].Value } |
? { $notfound -contains $_ } |
out-file C:\discovered.txt
"\something.txt"와 같은 파일을 찾고 있습니다. 당신은 그것을 변경해야합니다.
여전히 너무 느리고 찾을 수 없는 목록이 매우 큰 경우에는 .Net HashSet에 로드하는 것이 더 효율적일 수 있지만 필요하지 않으면 그렇게 하지 않습니다.