36 코어 시스템에서 10M 파일의 패턴을 빠르게 찾고 싶습니다. 이것을 시도했습니다.
find . -name '*.xml' -type f | xargs -P 20 grep "username" >> output
하지만 그 사이에 다른 결과도 얻었습니다.
이를 수행하는 더 좋은 방법이 있습니까?
미리 감사드립니다.
답변1
데이터가 RAID가 아닌 HDD에 있다는 점을 고려하면 병렬화를 통해 더 나은 성능을 얻을 수 있을지 의문입니다. 병목 현상은 CPU가 아닌 I/O일 가능성이 높습니다.
LC_ALL=C grep -rwF --include='*.xml' username . > /on/some/other/disk/output
아마도 당신이 얻을 수 있는 최고에 가깝습니다.
병렬화하려면 다음을 수행해야 합니다.
LC_ALL=C find . -name '*.xml' -type f -print0 |
LC_ALL=C xargs -r0P20 -n 1000 grep -HFw --line-buffered username > output
4KiB보다 긴 출력 라인(입력 라인 + 파일 경로 이름)이 없다고 가정하고, 20개의 동시 grep 라인이 결국 인터리브된다는 점에 유의하세요.
바라보다:
더 알아보기.
답변2
패턴이 너무 일반적이어서 그런 것 같아요. 일반적으로 명령줄 유틸리티는 stderr 또는 터미널에 오류를 인쇄합니다. 출력 파일에 들어가서는 안 됩니다.
답변3
이런 방식으로 파일을 grep
ping 하면 xml
검색 문자열이 포함된 전체 줄이 반환되거나, xml
파일에 개행 문자가 없으면 전체 파일 내용이 반환됩니다. 10M 파일에는 "기타"가 상당히 많습니다.
xml
@Kusalananda의 의견에 따르면, 더 나은 도구를 사용하여 파서를 강제로 사용하는 것은 grep
좋은 습관이 아니지만 , 주장한다면...xml
xmllint
반환 값을 제한하는 옵션을 확인하고 읽고 man
이를 사용하여 찾고 있는 일치 항목의 전체 길이를 정의하십시오.grep
-o
regex
username
속성인 경우
grep -o 'username="[^"]*"'
또는 더 나은
xmllint --xpath "//@username"
노드 라면 username
다음과 비슷하다.
grep -o "username>[^<][^<]*"
또는 더 나은
xmllint --xpath "//username"
모든 xmllint
쿼리에 대해 쿼리를 래핑하여 string()
속성이나 노드 텍스트를 추출하면 됩니다.
xmllint --xpath "string(//username)"
xmllint --xpath "string(//@username)"