sh에서 'find'의 '-prune'옵션을 사용하는 방법은 무엇입니까?
나는에서 주어진 예를 이해하지 못합니다. man find
누구든지 나에게 몇 가지 예와 설명을 줄 수 있습니까? 정규 표현식을 결합 할 수 있습니까?
더 자세한 질문은 다음과 같습니다.
changeall
와 같은 인터페이스를 가진 쉘 스크립트를 작성하십시오 changeall [-r|-R] "string1" "string2"
. 그것은의 접미사로 모든 파일을 찾을 것입니다 .h
, .C
, .cc
, 또는 .cpp
모든 항목 변경 string1
에를 string2
. -r
현재 디렉토리에만 머 무르거나 하위 디렉토리를 포함하는 옵션입니다.
노트:
- 재귀
ls
가 아닌 경우 허용되지 않으며find
및 만 사용할 수 있습니다sed
. - 시도
find -depth
했지만 지원되지 않았습니다. 그렇기 때문에-prune
도움이 될지 궁금 했지만의 예를 이해하지 못했습니다man find
.
EDIT2 : 과제를하고 있었는데 직접 마무리하고 싶기 때문에 질문을하지 않았습니다. 나는 이미 그것을하고 나눠 주었으므로 이제 모든 질문을 진술 할 수 있습니다. 또한을 사용하지 않고 과제를 완료 -prune
했지만 어쨌든 배우고 싶습니다.
내가 혼란스럽게 생각한 것은 테스트 (와 같은 )가 아니라 -prune
행동 -print
과 같은 것 -name
입니다. "할 일"목록을 변경 하지만 항상 true를 반환합니다 .
사용하는 일반적인 패턴 -prune
은 다음과 같습니다.
find [path] [conditions to prune] -prune -o \
[your usual conditions] [actions to perform]
테스트의 첫 부분 (및 최대 포함 )은 실제로 원하는 항목 (예 : 정리 하지 않으려 는 항목)에 대해 false 를 반환 하기 때문에 거의 항상 -o
(논리적 OR)을 원합니다 .-prune
-prune
예를 들면 다음과 같습니다.
find . -name .snapshot -prune -o -name '*.foo' -print
".snapshot"디렉토리에없는 "* .foo"파일을 찾을 수 있습니다. 이 예에서, -name .snapshot
최대하게 [conditions to prune]
하고 -name '*.foo' -print
있다 [your usual conditions]
및 [actions to perform]
.
중요 사항 :
원하는 결과를 인쇄하기 만하면 작업을 수행하지 않아도됩니다
-print
. 일반적 으로을 사용할 때는 그렇게하고 싶지 않습니다-prune
.find의 기본 동작은 끝에 아이러니 한 동작 이외의 동작이없는 경우 동작 과 함께 전체 식 을 "및"
-print
수행하는 것-prune
입니다. 그것은 이것을 쓰는 것을 의미합니다 :find . -name .snapshot -prune -o -name '*.foo' # DON'T DO THIS
이것을 쓰는 것과 같습니다.
find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS
이것은 정리하고있는 디렉토리의 이름도 인쇄한다는 것을 의미합니다. 일반적으로 원하는 이름이 아닙니다. 대신
-print
원하는 작업 을 명시 적으로 지정하는 것이 좋습니다.find . -name .snapshot -prune -o -name '*.foo' -print # DO THIS
"정상 조건"이 프룬 조건과 일치하는 파일과 일치하면 해당 파일이 출력에 포함 되지 않습니다 . 이 문제를 해결하는 방법은
-type d
프룬 조건에 술어를 추가하는 것 입니다.예를 들어, 우리가 시작한 디렉토리를 제거하려고한다고 가정하고
.git
(이것은 다소 다소 고안된 것입니다-일반적으로 정확히 이름을 가진 것만 제거하면 됩니다.git
), 이외의 파일을 포함하여 모든 파일을 보려고했습니다.gitignore
. 이것을 시도 할 수 있습니다 :find . -name '.git*' -prune -o -type f -print # DON'T DO THIS
이것은 출력에 포함 되지 않습니다
.gitignore
. 고정 버전은 다음과 같습니다.find . -type d -name '.git*' -prune -o -type f -print # DO THIS
추가 팁 : GNU 버전 find
의을 사용하는 경우 texinfo 페이지에 대한 find
맨 페이지보다 자세한 설명이 있습니다 (대부분의 GNU 유틸리티에 해당됨).
일부가 말했듯 이 -prune은 어떤 디렉토리 로 도 내려가는 것을 막지 않습니다 . 적용된 테스트와 일치하는 디렉토리로 내려 가지 않습니다. 아마도 일부 예제가 도움이 될 것입니다 (정규 예제의 맨 아래 참조). 너무 길어서 죄송합니다.
$ find . -printf "%y %p\n" # print the file type the first time FYI
d .
f ./test
d ./dir1
d ./dir1/test
f ./dir1/test/file
f ./dir1/test/test
d ./dir1/scripts
f ./dir1/scripts/myscript.pl
f ./dir1/scripts/myscript.sh
f ./dir1/scripts/myscript.py
d ./dir2
d ./dir2/test
f ./dir2/test/file
f ./dir2/test/myscript.pl
f ./dir2/test/myscript.sh
$ find . -name test
./test
./dir1/test
./dir1/test/test
./dir2/test
$ find . -prune
.
$ find . -name test -prune
./test
./dir1/test
./dir2/test
$ find . -name test -prune -o -print
.
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2
$ find . -regex ".*/my.*p.$"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test/myscript.pl
$ find . -name test -prune -regex ".*/my.*p.$"
(no results)
$ find . -name test -prune -o -regex ".*/my.*p.$"
./test
./dir1/test
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test
$ find . -regex ".*/my.*p.$" -a -not -regex ".*test.*"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
$ find . -not -regex ".*test.*" .
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2
일반적으로 우리가 리눅스에서 일하는 기본 방식과 생각 방식은 왼쪽에서 오른쪽입니다.
따라서 먼저 찾고있는 것을 작성하십시오.
find / -name "*.php"
그런 다음 enter 키를 누르고 원하지 않는 디렉토리에서 너무 많은 파일을 가져오고 있음을 알 수 있습니다. 마운트 된 드라이브를 검색하지 않도록 / media를 제외 시키십시오.
이제 이전 명령에 다음을 추가하면됩니다.
-print -o -path '/media' -prune
최종 명령은 다음과 같습니다.
find / -name "*.php" -print -o -path '/media' -prune
............... | <--- 포함 ---> | .................... | <- -------- 제외 ---------> |
I think this structure is much easier and correlates to the right approach
Adding to the advice given in other answers (I have no rep to create replies)...
When combining -prune
with other expressions, there is a subtle difference in behavior depending on which other expressions are used.
@Laurence Gonsalves' example will find the "*.foo" files that aren't under ".snapshot" directories:-
find . -name .snapshot -prune -o -name '*.foo' -print
However, this slightly different short-hand will, perhaps inadvertently, also list the .snapshot
directory (and any nested .snapshot directories):-
find . -name .snapshot -prune -o -name '*.foo'
The reason is (according to the manpage on my system):-
If the given expression does not contain any of the primaries -exec, -ls, -ok, or -print, the given expression is effectively replaced by:
( given_expression ) -print
That is, the second example is the equivalent of entering the following, thereby modifying the grouping of terms:-
find . \( -name .snapshot -prune -o -name '*.foo' \) -print
This has at least been seen on Solaris 5.10. Having used various flavors of *nix for approx 10 years, I've only recently searched for a reason why this occurs.
Prune is a do not recurse at any directory switch.
From the man page
If -depth is not given, true; if the file is a directory, do not descend into it. If -depth is given, false; no effect.
Basically it will not desend into any sub directories.
Take this example:
You have the following directories
- /home/test2
- /home/test2/test2
If you run find -name test2
:
It will return both directories
If you run find -name test2 -prune
:
It will return only /home/test2 as it will not descend into /home/test2 to find /home/test2/test2
I am no expert at this (and this page was very helpful along with http://mywiki.wooledge.org/UsingFind)
Just noticed -path
is for a path that fully matches the string/path that comes just after find
(.
in theses examples) where as -name
matches all basenames.
find . -path ./.git -prune -o -name file -print
blocks the .git directory in your current directory ( as your finding in .
)
find . -name .git -prune -o -name file -print
blocks all .git subdirectories recursively.
Note the ./
is extremely important!! -path
must match a path anchored to .
or whatever comes just after find if you get matches with out it (from the other side of the or '-o
') there probably not being pruned! I was naively unaware of this and it put me of using -path when it is great when you don't want to prune all subdirectory with the same basename :D
Show everything including dir itself but not its long boring contents:
find . -print -name dir -prune
If you read all the good answers here my understanding now is that the following all return the same results:
find . -path ./dir1\* -prune -o -print
find . -path ./dir1 -prune -o -print
find . -path ./dir1\* -o -print
#look no prune at all!
But the last one will take a lot longer as it still searches out everything in dir1. I guess the real question is how to -or
out unwanted results without actually searching them.
So I guess prune means don't decent past matches but mark it as done...
http://www.gnu.org/software/findutils/manual/html_mono/find.html "This however is not due to the effect of the ‘-prune’ action (which only prevents further descent, it doesn't make sure we ignore that item). Instead, this effect is due to the use of ‘-o’. Since the left hand side of the “or” condition has succeeded for ./src/emacs, it is not necessary to evaluate the right-hand-side (‘-print’) at all for this particular file."
find
builds a list of files. It applies the predicate you supplied to each one and returns those that pass.
This idea that -prune
means exclude from results was really confusing for me. You can exclude a file without prune:
find -name 'bad_guy' -o -name 'good_guy' -print // good_guy
All -prune
does is alter the behavior of the search. If the current match is a directory, it says "hey find
, that file you just matched, dont descend into it". It just removes that tree (but not the file itself) from the list of files to search.
It should be named -dont-descend
.
참고URL : https://stackoverflow.com/questions/1489277/how-to-use-prune-option-of-find-in-sh
'Programing' 카테고리의 다른 글
도커 컨테이너에서 호스트 포트에 액세스하는 방법 (0) | 2020.05.06 |
---|---|
동적 프로그래밍을 사용하여 가장 긴 하위 시퀀스를 결정하는 방법은 무엇입니까? (0) | 2020.05.06 |
String, StringBuffer 및 StringBuilder (0) | 2020.05.06 |
gradle 의존성이 새로운 버전인지 확인하는 방법 (0) | 2020.05.06 |
web.config 파일을 사용하여 HTTPS를 강제 실행하는 방법 (0) | 2020.05.06 |