2012-09-10 6 views
1

내 문제는 Powershell입니다. 매우 큰 폴더가 있습니다. 내부자는 약 1 600 000 개의 하위 폴더입니다. 내 작업은 6 개월 이상 된 빈 폴더 나 파일을 모두 지우는 것입니다. 나는 foreach 문으로 루프를 작성하지만 파워 쉘이 시작하기 전에 연령대 소요 ->Powershell로 많은 폴더를 확인하십시오.

...

foreach ($item in Get-ChildItem -Path $rootPath -recurse -force | Where-Object -FilterScript { $_.LastWriteTime -lt $date }) 
{ 
# here comes a script which will erase the file when its older than 6 months 
# here comes a script which will erase the folder if it's a folder AND does not have child items of its own 

...

문제점 : 내 내부 메모리가 가득 (4 기가 바이트) 도착 그리고 나는 더 이상 제대로 작동하지 않습니다. 내 추측 : powershell은 모든 1 600 000 개의 폴더를로드하고 그 후에 만 ​​필터를 시작합니다.

이것을 방지 할 수 있습니까?

답변

0

정확합니다. 모든 1.6M 폴더 또는 적어도 이들에 대한 참조가 한 번에로드됩니다. 가장 좋은 방법은 왼쪽 & 형식의 필터를 필터링하는 것입니다. 가능한 경우 모두 Where-Object을 누르기 전에 해당 폴더를 삭제하십시오 (불행히도 gci은 AFAICT라는 날짜 필터를 지원하지 않습니다). 또한 파이프 라인에 물건을두면 메모리를 적게 사용하게됩니다.

다음은 조건에 맞는 폴더 만 $items으로 제한 한 다음 해당 개체에 대한 루프를 수행합니다.

$items = Get-ChildItem -path $rootpath -recurse -force | ?{ $_.LastWriteTime -lt $date } 
foreach ($item in $items) { 
# here comes a script which will erase the file when its older than 6 months 
# here comes a script which will erase the folder if it's a folder AND does not have child items of its own 
} 

또는 더 간소화이 지난 경우

function runScripts { 
    # here comes a script which will erase the file when its older than 6 months. Pass $input into that script. $input will be a folder. 
    # here comes a script which will erase the folder if it's a folder AND does not have child items of its own Pass $input into that script. $input will be a folder. 
} 
Get-ChildItem -path $rootpath -recurse -force | ?{ $_.LastWriteTime -lt $date }|runScripts 

을, 당신은 ($input)으로 운영 할 수있는 매개 변수로 파이프 라인 개체를 사용하는 함수로 당신 때문에 runScripts를 사용하는 중간 개체를 사용하는 대신 파이프 라인을 통해 모든 것을 보낼 수 있습니다 (더 많은 메모리를 소비하게 됨).

+0

감사합니다. 저는 더 작은 환경에서 테스트했습니다. (106 000 폴더) 원본 스케치에서 약 73 초가 걸렸습니다. modifikations (능률화)로 나는 단지 51 초를 필요로했다. 감사합니다. – user1660311

+0

아, 내부 메모리 문제가 해결 된 것 같습니다 :) – user1660311

관련 문제