저는 Windows 생태계를 처음 접했습니다. 나는 특정 문자열에 대해 수천 개의 파일(어쩌면 100개)을 검색하는 프로그램을 작성하는 임무를 맡았습니다. 일치해야 하는 문자열은 숫자와 문자로만 구성된 일련번호이며 20자 미만입니다. 현재 내 프로그램은 다음 명령을 실행하고 있습니다.
findstr /i /m /s "searchStr" "C:\Directory\To\Search\*.*"
위 명령은 작동하지만 너무 느립니다. 특정 일련 번호를 포함할 수 있는 파일은 첫 번째 줄에만 일련 번호를 갖습니다.
디렉토리에서 첫 번째 줄에만 특정 문자열이 포함된 모든 파일을 재귀적으로 검색하는 효율적인 방법을 아는 사람이 있습니까?
답변1
PowerShell(v3.0+)에서는 아마도...
Get-ChildItem -Path x:\pathto\*.log `
| ForEach-Object {
if (Get-Content -LiteralPath $_ -First 1 `
| Select-String -SimpleMatch -Pattern 'serialnumber')
{
Write-Output $_
}
}
Get-ChildItem
하위 폴더 등을 반복할 수 있는 다양한 매개변수 Get-Content
파일에서 더 많거나 적은 콘텐츠를 얻을 수 있습니다 . Select-String
더 복잡한 일치(정규식, 대소문자 구분 등)를 수행할 수 있습니다 .
답변2
를 사용할 필요가 없는 경우 몇 가지 옵션을 제안할 수 있지만 findstr
, 먼저 특정 파일 형식의 파일로 검색을 제한할 수 있는지 확인해야 합니다. 그러면 작업 속도가 확실히 빨라집니다.
파일로케이터 라이트내 경험으로는 파일을 찾고 내용을 확인하는 것이 더 빠릅니다. "파일 이름"(해당하는 경우) 및 "포함된 텍스트" 필드와 시작 디렉터리를 모두 입력해야 합니다.
ag -il "searchStr"
:아그속도를 위해 제작되었으므로 결과를 빠르게 제공해야 합니다. 바이너리 파일은 이미 기본적으로 건너뛰지만 가능하다면 파일 유형별로 검색을 제한하십시오. 아래에서도 사용 가능시그윈.find -exec awk 'BEGIN {IGNORECASE=1} NR==1 && /searchStr/ {print FILENAME": "$0}' {} \;
Cygwin이나 다른 POSIX와 유사한 환경을 사용할 수 있는 경우 첫 번째 줄만 검색하는 방법에 대한 아이디어를 확인하려면 이것을 시도해 보십시오. 결합하여find
파일 이름을 얻고(그리고 필터링도 하길 바랍니다)awk
첫 번째 줄을 확인하고 파일 이름과 함께 인쇄합니다.find | parallel 'perl -lane '\'' print "$ARGV: $_" if $. == 1 and /searchStr/i '\'' {}'
작업 속도를 높이는 또 다른 아이디어는 사용 가능한 코어와 스레드를 작동시키는 것입니다.GNU 병렬입니다. 이 예제는 sports 이지만 위와perl
동일합니다 . 명령 분석은 다음과 같습니다.awk
3.
find
현재 디렉터리와 그 하위 디렉터리에서 파일을 찾습니다. 검색할 다른 디렉터리와 필터링할 파일 패턴 또는 확장자를 지정할 수 있습니다find /cygdrive/c/Directory/To/Search -iname "*.txt"
.|
"파이프", 즉 결과 목록을 다음 명령에 공급합니다.parallel
다음 명령을 병렬로 실행합니다.perl
텍스트 파일 조작에 탁월한 스크립팅 언어는sed
또는awk
.-lane
Perl 단일 라이너에 유용한 스위치 세트입니다.'\''
이스케이프된 아포스트로피는 이미 뒤에 설정된 아포스트로피를 열었기 때문에 필요합니다parallel
.print "$ARGV: $_"
파일 이름($ARGV
), 콜론, 공백 및 전체 줄($_
)을 인쇄합니다.if
다음 조건이 충족되는 경우에만 이전 명령을 실행하십시오.$. == 1
줄 번호($.
)는 1( )과 같습니다1
. 즉, 파일의 첫 번째 줄을 보고 있습니다.and
다음 조건도 충족해야 합니다./searchStr/i
검사 중인 줄에는searchStr
대소문자를 구분하지 않고 텍스트가 포함되어 있습니다.'\''
또 다른 이스케이프된 아포스트로피는 명령의 끝을 표시합니다perl
.{}
parallel
이는 에서 전달한 각 파일 이름으로 대체됩니다find
.'
지시 끝parallel
.
업데이트:작업이 첫 번째 줄에만 바인딩되어 있어도 전체 파일을 읽 awk
습니다 . perl
해결책은 2행에서 설명을 명시적으로 중지하는 것입니다.
find -exec awk 'BEGIN {IGNORECASE=1} NR > 1 {exit} /searchStr/ {print FILENAME": "$0}' {} \;
find | parallel 'perl -lape '\'' exit if $. == 2; print "$ARGV: $_" if /searchStr/i '\'' {}'