*nix grep의 PowerShell 아날로그 수행

*nix grep의 PowerShell 아날로그 수행

아래 PowerShell 코드를 최적화할 수 있는 방법이 있습니까? (여러 텍스트 파일에 포함된 문자열을 기준으로 특정 줄을 단일 항목으로 끌어옵니다.)

$ErrorActionPreference = "Continue"
Start-Transcript -path D:\0xAC1CC07A.log -append
$OutFile = "D:\0xAC1CC07A.txt"
echo "filtering 0xAC1CC07A"
ForEach ($filenm in ((get-childitem -Path D:\FILES\* -include ubuntlive1mb_?????_201509*.txt -recurse -force))) 
{
 $filenm.fullName;
 (Get-Content $filenm) | select-string "0xAC1CC07A" | Add-Content $OutFile
}
Stop-Transcript

소규모 작업 부하에서는 잘 작동하지만 160K 텍스트 파일(총 200GB 이상)에서는 Win2008R2 VM에서 4일 이상 작동합니다. 놀랍게도 유사한 가상 하드웨어의 Ubuntu 14.04는 4시간 이내에 작업을 수행했습니다.

grep --no-filename "0xac1cc07a" ./FILES/ubuntlive1mb_?????_201509*.txt >>./0xAC1CC07A.txt

또는 더 정확하게는:

find ./FILES -name "ubuntlive1mb_?????_201509*.txt" -type f -print0 | xargs -0 grep --no-filename "0xac1cc07a" $1 >>./0xAC1CC07A.txt

저는 PowerShell이나 *nix에 능숙하지 않습니다. 위 스크립트는 모두 구글링과 복사-붙여넣기로 만든 것입니다.

Windows 상자는 목록에서 DOS 파일 이름과 디렉터리 업데이트를 비활성화하여 파일 시스템을 최적화했습니다. 우분투는 방금 설치되었습니다.

답변1

이 매우 간단한 Powershell 스크립트는 원하는 작업을 수행합니다.

$OutFile = "D:\0xAC1CC07A.txt"
Get-ChildItem -Path D:\FILES\ubuntlive1mb_?????_201509*.txt -Recurse | Foreach-Object { Select-String -Path $_ -Pattern "0xAC1CC07A" } | Foreach-Object { Add-Content -Path $OutFile -Value $_.Line }

그러면 일치하는 줄이 $OutFile 텍스트 파일에 추가됩니다. Line 속성 대신 Filename, Path 및 LineNumber 속성을 사용하여 이를 사용하여 일치하는 줄의 줄 번호나 파일 이름을 얻을 수도 있습니다.

많은 파일에 대해 실행될 스크립트를 테스트하고 싶지만 모든 파일 검사가 완료될 때까지 기다리고 싶지 않은 경우 Select-Object cmdlet을 사용하여 검사할 파일 수를 제한할 수 있습니다.

예:

Get-ChildItem -Path D:\FILES\ubuntlive1mb_?????_201509*.txt | Select-Object -First 100 | Foreach-Object { Select-String -Path $_ -Pattern "0xAC1CC07A" } | Foreach-Object { Add-Content -Path $OutFile -Value $_.Line }

그러면 Get-ChildItem에서 반환된 처음 100개의 텍스트 파일에 대해서만 위 스크립트가 실행됩니다.

답변2

약간 다른 출력이 표시되지만(필요한 경우 처리할 수 있음) 내가 본 바에 따르면 파일 내용을 가져오는 대신 파일에서 직접 Select-String을 사용하는 것이 훨씬 더 빠릅니다. 첫 번째.

Select-String "0xAC1CC07A" -Path $filenm.FullName | Add-Content $OutFile

파일에 추가하기 전에 먼저 출력을 확인하여 원하는 방식으로 얻을 수 있도록 하십시오.

속도는; Get-ChildItem은 PowerShell에서 속도가 느린 것으로 악명이 높으며(PowerShell은 개체의 텍스트 표현이 아닌 개체를 가져오는 것을 좋아하기 때문에) 이에 대한 다양한 해결 방법이 있습니다.

그러나 코드의 Get-ChildItem-라인은 최적화할 수 있습니다. 제가 본 바로는 필터를 사용하는 것이 일반 소비자용 7.2k HDD에서 포함/제외를 사용하는 것보다 약 3.5배 더 빠릅니다.

Get-ChildItem -Path "D:\FILES" -Filter "ubuntlive1mb_?????_2015090101*.txt" -Recurse -Force

메모리가 제대로 작동한다면 이전 버전의 PowerShell에는 필터와 관련된 몇 가지 문제가 있었습니다. 예를 들어 확장명이 .htm인 모든 파일을 원하는 경우 확장명이 .html인 파일도 선택합니다(필터링은 했지만 필터링은 *.htm*하지 않은 것처럼 *.htm). 그래서 당신은 그것에 대해주의를 기울이고 싶을 수도 있습니다.

관련 정보