[완료] find에서 -prune 옵션에 대해서..
글쓴이: nomail / 작성시간: 월, 2014/02/10 - 4:42오전
find의 맨페이지를 보면 -prune 옵션에 대해 나오는데
지정한 이름이 디렉토리 일때 그 이하 서브디렉토리는 탐색하지 않는다는 설명이 있습니다.
그런데 제가 잘못 이해한건지.. 테스트를 해보면 의도한대로 동작하지 않습니다.
cd /etc find . -name 'config*' ./pcmcia/config.opts ./i3/config ./i3/config.keycodes ./vmware/hostd/config.xml ./vmware/config
위 결과에서 i3 디렉토리를 제외하고 검색 하고자 했을 때 다음 코드를 실행하면,
find -name 'config*' \( -path '*i3*' -prune \) ./i3/config ./i3/config.keycodes
오히려 반대의 결과가 나옵니다. 맨페이지 내용이랑 결과가 다른데.. 왜 이렇게 나오는 건가요?
Forums:
find -name 'config*' \( -path
find -name 'config*' \( -path '*i3*' -prune \)
는 bash 문법에 어긋나는 명령어 같습니다.
-name 'config*' 조건에서 디렉토리가 일단
-name 'config*' 조건에서 디렉토리가 일단 걸러집니다. config로 시작하는 이름의 디렉토리가 없습니다.
이 결과는 다 파일 입니다. 디렉토리가 아닙니다.
-path 'i3' 조건에서 두개만 남습니다.
두 파일은 디렉토리가 아니기 때문에 -prune은 아무일도 하지 않고 '참'을 반환 합니다.
맨페이지의 이 설명대로라면 이렇게 됩니다.
앞서 살펴본 것 처머 이 표현식에서는 -prune에 디렉토리가 전달되지 않았기 때문에 하는일이 실질적으로 없습니다.
이 명령과 완전히 같은 명령이 됩니다. -name 'config*'의 결과 중에서 디렉토리가 있었다면 -prune이 실제로 뭔가 하는 일이 생겼을 겁니다. 출력 결과에서 그 디렉토리 이하의 파일들은 걸러지겠죠. 그렇다고 해도 ./i3 디렉토리를 결과에서 제외할려는 원래의 목적은 달성하지 못합니다.
특정 결과를 제외하기 위해서 간단하게는 이렇게 쓸 수 있을 겁니다.
좀 더 분명한 의미로 써 보면,
-and와 -print는 암묵적으로 적용되는 것이니,
이렇게 쓸 수 있겠지요.
-prune 저도 이 글 보고 읽어 봤더니 어떻게 쓰라는 건지 이해하기가 참 애매하더군요. 일단 -prune이 조건이 아니고 액션이라는 사실을 잊지 말아야 합니다. -print, -exec 같은 액션 입니다. 액션을 하고 참을 반환한다. 이게 중요 합니다.
그리고 -prune이 하는 일은 디렉토리를 만났을 때 find가 그 디렉토리로 들어가지 못하게 하는 겁니다. find가 손에 쥐고 조건 검사를 하려는 그 파일 목록들중 일부를 쳐낼 수가 있습니다.
그래서 -prune이 효과적으로 쓰일 수 있는 경우는 불필요한 검사 횟수를 크게 줄일 수 있다는 점 같습니다.
조금 억지스러워 보이지만 -prune의 효과를 확실히 보여주는 것 같습니다. /usr, /home, /var 이 세 디렉토리 만을 찾는 조건인데 첫번째 경우는 각 디렉토리의 모든 파일과 디렉토리에 대해서 계속 검사를 합니다. 두번째 경우는 같은 결과를 수행하지만 -prune 덕분에 검사 횟수가 현저히 줄어 듭니다. 제 컴퓨터에서 대충 25초 이상 차이 나네요.
그럼 반대로 /usr, /home, /var를 제외한 나머지 부분에서만 어떤 조건을 검사하고 싶다면 어떻게 할까요.
출력 결과를 좀 간단하게 할려고 임의의 디렉토리 구조를 만들어 봤습니다.
여기서 ./2 디렉토리를 제외한 모든 파일에 find 검색을 하고 싶다. 이게 우리 목적 입니다. ./2 디렉토리 아래에 파일이 한 수백만개 있다 그러면 이 때 -prune을 쓰는게 말이 됩니다.
./2/2, 다시 말하면 ./2/* 는 제외 했는데 ./2는 여전히 나오네요. 그런데 이 때 명시적으로 -print를 써주면 ./2가 안나옵니다.
아까 맨페이지에서 인용한 부분중에 액션이 -prune 뿐이면 -print가 자동적으로 붙는다고 했습니다. 이렇게 되겠죠.
-prune은 액션을 하고 참을 반환하기 때문에 ./2도 -print에 걸려 듭니다.
갈수록 복잡해지는데 헷갈림 없이 -prune을 쓰려면 다음 패턴을 기억해야 할 것 같습니다.
제일 뒤에 있는 -action을 생략하면 암묵적으로 전체 표현식에 -print가 적용 되므로 -prune이 발동된 그 디렉토리도 출력 결과에 포함 된다는 사실을 잊지 마세요.
아니면 우리가 find를 쓸 때 이렇게 많이 씁니다.
이렇게 해서 결과를 출력하죠 보통 -print는 생략하구요. 이 때 결과 중에서 디렉토리 통채로 제거할 경우, '-print -or -path ./path1 -prune' 이렇게 붙여 줍니다.
-print를 빼먹으면 ./path1도 결과에 출력 된다는 사실을 잊지 맙시다. 찡긋.
이 글을 학습, 번역 하였습니다.
http://stackoverflow.com/questions/1489277/how-to-use-prune-option-of-find-in-sh
긴글 답변 주셔서 정말 감사드립니다. 코드랑 같이
긴글 답변 주셔서 정말 감사드립니다.
코드랑 같이 적는게 쉽지가 않는데 정말 무한한 정성이 느껴집니다.
이렇게 부연설명이 필요한데.. 왜 맨페이지에는 대충 적어놨을까요ㅜㅜ
덧글 설명을 3번 정독하고 완전히 이해했구요. 제 시스템에서 여러번 테스트 해보니 확실히 사용법을 알겠습니다.
-prune 옵션의 핵심은, 조건이 아니라 액션이라는 것과
이 부분이네요.
그리고 find -or 조건식이 제가 이해하는 or의 개념이 아니라 좀 헷갈렸는데 가령,
expr1이 true 이면 expr2는 무시한다는 의미인데, 그렇다면
위에서 -or 앞쪽의 print는 모두 true 이니까, 뒤쪽 prune은 실행이 안될거라고 생각했습니다.
곰곰히 생각해보니 이미 디렉토리를 읽었을 때 -or 앞쪽 -name 조건식이 false가 되고 prune 액션 후, 그 디렉토리는 걸러지는 것 같네요.
상세한 설명 덕분에 find 명령을 확실히 배웠습니다. 정말 감사드립니다^^
info find 하시면 좀 상세한 문서를 보실 수
info find 하시면 좀 상세한 문서를 보실 수 있습니다. KDE나 GNOME 도움말 브라우저로 보시면 좀 편합니다.
이렇게 보면 좀 더 머릿속으로 그리기가 편할 것 같습니다. -path로 들어오는 파일은 이미 조건 3가지 중 하나에서 탈락한 파일 입니다.
부연 설명도 감사합니다. 쉽게 설명해주셔서 파악하는데
부연 설명도 감사합니다.
쉽게 설명해주셔서 파악하는데 많은 도움이 되었구요.
처음 맨페이지 봤을 때 복잡해 보였는데 옵션과 조건식, 액션의 개념구분만 있으면 좀 손 쉽게 사용할 수 있을 것 같습니다^^
죄송스럽지만..
흑.. 회사 UNIX 인데 info find 가 안먹히는군요 ㅜ
반복해서 읽었는데 이해가 잘 안가 글을 남깁니다..
ex) ./~.sh /var *.log 라 쳤을때 /var 에 있는 *.log 로 시작하는 것들을 묶으려고 합니다 그런데 하위로 계속 넘어가게 되어
-prune 을 쓰려고 하는데요
find . -name '*.log' \( -path '*tes*' -o -prune -print \)
하여서 성공은 했는데
디렉은 이렇습니다만 제가 해석하기에 위와 같이 명령어를 치면 .ssh 는 나와야할법 한데... 죄송합니다 이해가 덜 됬나봐요...
1. find 에서 ./(블라블라) < - 이런류의 파일만 받음
2. ./(블라블라)/(블라블라) X < - 즉 하위까지 검색 안함
3. 여기에서 (\ 구문을 썼는데 여기서의 결과가 \( 앞의 -name '*.log' 에 들어가게 되는 건가요...?
도움을 요청..합니다..ㅜㅜ
find -name 'config*' -print
한 줄 요약:
dontdieych님 감사합니다.
요새 저도 -prune과 -or 때문에 헷갈려서 이리저리 검색 중이였는데
상세하고 자세한 설명덕분에 이해할 수 있게됐습니다~
find 하다가 man find 보다가 뭔가 애매하게
find 하다가 man find 보다가 뭔가 애매하게 궁금해서 구글 검색 하다가 들어 왔는데 제가 8년 전 즈음에 쓴 글이 저한테 답을 주네요.
글타래 읽다 보니 제 아바타가 보이길래 뭐지? 했는데 제가 쓴 답글이 있네요.
사람의 기억력이란 정말 믿지 말아야 할 것 같습니다. 8년 전에 저렇게 길고 장황하게 -prune 에 대해서 썼는데 오늘 기억 안나서 다시 검색해보는 날 이네요.
댓글 달기