find ./ -exec grep "" {} \; 이 비효율적인 조합입니까?

k1d0bus3의 이미지

 find ./Girlgroup ! -name "Sistar" -exec grep -r "Sexy" {} \;

Girlgroup 디렉토리는 1~2GB이고 수만개이상의 텍스트파일로 이루어져 있습니다.
이 중에서 "Sexy"가 들어간 줄을 확인하고 싶습니다.
문제는 위와 같은 명령어 하나만 해도, 25분씩이나 걸립니다. (find명령어가 쿼드코어 CPU점유율 16% 먹네요.HDD사용)

원래 저 정도의 시간이 걸리는 겁니까? 아니면 제가 비효율적인 조합을 쓰는 걸까요?

qiiiiiiiip의 이미지

먼저 grep에 -r 은 없어야할 듯.
일단 파일리스트를 만들고, 여러 파일에 대해서 grep을 한꺼번에 하는것이 효율적일 것 같네요..

find ./Girlgroup ! -name "Sistar" | xargs grep "Sexy"

파일이름에 공백이 있다면

find ./Girlgroup ! -name "Sistar" -print0 | xargs -0 grep "Sexy"

입력파일이 크고 pattern이 단순하다면 -F 를 주면 grep 속도를 많이 높일 수 있습니다.

find ./Girlgroup ! -name "Sistar" -print0 | xargs -0 grep -F "Sexy"

1만개 파일에 대해서 해보면, 20초에서 0.5초이내로 줄어드네요..

$ for i in $(seq -f "%06g" 0 9999); do
echo $RANDOM > $i
done
$ time find . -name "0*" -exec grep 1234 {} \; > /dev/null
find . -name "0*" -exec grep 1234 {} \; > /dev/null  0.19s user 1.12s system 6% cpu 20.487 total
$ time find . -name "0*" | xargs grep 1234 > /dev/null
find . -name "0*"  0.01s user 0.00s system 84% cpu 0.012 total
xargs grep 1234 > /dev/null  0.00s user 0.02s system 66% cpu 0.035 total

k1d0bus3의 이미지

|xarg 로 하니까 확실히 빨라졌네요 감사합니다.

익명 사용자의 이미지

파일 갯수만큼 grep를 새로 띄워줘야 한다는 점에서 비효율적이긴 하죠.
특히 grep 자체가 여러 파일을 잇달아 처리할 수 있는 기능이 있으니 더더욱.

그러니 xargs를 써서 파일 리스트를 커맨드 라인 파라미터로 뭉쳐서 넣어주는 게 일단 바로 떠오르는 해결책이긴 한데
문제는, 커맨드 라인 파라미터에도 길이 제한이 있을 수 있다는 겁니다.
find의 조건에 맞는 파일 갯수를 예상할 수 없다면 문제가 될 수 있다는 거죠.

그거까지 고려해서 적당히 끊어 넣어주는 쉬운 방법이 있으면 좋겠는데 저는 잘 모르겠네요. 혹시 아시는 분?

chanik의 이미지

혹시나 해서 해 봤는데, xargs가 알아서 끊어주네요.
아래의 세 가지 방식중 [2]와 [3] 모두, 예상과는 달리
한 방에 몽땅 넘겨주지 않고 적당히 끊어서 여러 번 명령을 실행해 줬습니다.

[1] find -exec .. \;
[2] find -exec .. \+
[3] find -exec .. -print0 | xargs -0

구닥다리 버전인 CentOS 5.11에서 해 봤고,
아래와 같이 echo 실행횟수와 실행시 넘겨받은 command line argument length를 표시하게 했습니다.

$ lsb_release -d
Description:    CentOS release 5.11 (Final)
 
# [1] 시킨대로, 파일 갯수만큼 echo 실행됨
$ find /usr -exec echo {} \; | awk '{print NR, ":", length($0)}'
1 : 4
2 : 8
3 : 16
.
.
211853 : 81
211854 : 79
211855 : 29
 
# [2] command line 길이가 128KB 정도 되도록 끊어서 echo 실행됨
$ find /usr -exec echo {} \+ | awk '{print NR, ":", length($0)}'
1 : 128993
2 : 129012
3 : 128993
.
.
85 : 128967
86 : 129007
87 : 51871
 
# [3] command line 길이가 128KB 정도 되도록 끊어서 echo 실행됨
$ find /usr -print0 | xargs -0 echo | awk '{print NR, ":", length($0)}'
1 : 128112
2 : 128079
3 : 128108
.
.
85 : 128115
86 : 128081
87 : 128121

그리고, xargs -s 65536 식으로 강제로 길이 제한을 줄 수도 있네요.

$ find /usr -print0 | xargs -0 -s 65536 echo | awk '{print NR, ":", length($0)}'
1 : 65519
2 : 65506
3 : 65518
.
.
169 : 65465
170 : 65530
171 : 9179

익명 사용자의 이미지

제가 하나만 알고 둘은 몰랐군요.

그러면 이런 경우엔 바로 아무 생각 없이 xargs를 쓰는 편이 이득이네요.
귀중한 지식 배우고 갑니다.

ymir의 이미지

이런 경우라면 그냥 grep 의 recursive 와 exclude 옵션만으로도 될 것 같은데 말이죠..?

$ grep -r --exclude=Sistar Sexy

성능이 이슈라면 GNU parallel 도 고려해 보면 좋을 것 같네요.

http://stackoverflow.com/questions/9066609/fastest-possible-grep

grep speed up 으로 검색해 보니 재미난 게 있네요.

http://www.inmotionhosting.com/support/website/ssh/speed-up-grep-searches-with-lc-all

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.