TL; DR : 가장 좋은 방법은 -exec rm
대신에 사용하는 것입니다 -delete
.
find a \( -name b -prune \) -o -type f -exec rm {} +
설명:
-delete
함께 사용하려고 할 때 왜 불만 이 -prune
있습니까?
짧은 답변 : 때문에 -delete
의미 -depth
와 -depth
만드는 -prune
효과.
우리는 긴 대답에 오기 전에 첫번째와없는 발견의 행동을 관찰 -depth
:
$ find foo/
foo/
foo/f1
foo/bar
foo/bar/b2
foo/bar/b1
foo/f2
단일 디렉토리에서의 순서에 대한 보장은 없습니다. 그러나 디렉토리가 내용보다 먼저 처리된다는 보장이 있습니다. 참고 foo/
모든 전에 foo/*
하고 foo/bar
어떤 전에 foo/bar/*
.
이것은로 되돌릴 수 있습니다 -depth
.
$ find foo/ -depth
foo/f2
foo/bar/b2
foo/bar/b1
foo/bar
foo/f1
foo/
이제는 모두 foo/*
앞에 나타납니다 foo/
. 와 동일합니다 foo/bar
.
더 긴 답변 :
-prune
찾기가 디렉토리로 내려 가지 않도록합니다. 다시 말해 -prune
디렉토리의 내용을 건너 뜁니다. 귀하의 경우 -name b -prune
찾기가 이름이있는 디렉토리로 내려 가지 않습니다 b
.
-depth
디렉토리 자체보다 먼저 디렉토리의 내용을 처리합니다. 이는 find가 디렉토리 항목을 처리 할 때까지 b
해당 내용이 이미 처리되었음을 의미합니다. 따라서 사실상 효과 -prune
가 없습니다 -depth
.
-delete
의미 -depth
는 다음 빈 디렉토리를 먼저 파일을 삭제 할 수 있습니다. -delete
비어 있지 않은 디렉토리를 삭제하지 않습니다. -delete
비어 있지 않은 디렉토리 를 강제 로 삭제하거나 -delete
암시 하지 않도록 옵션을 추가하는 것이 가능할 것 -depth
입니다. 그러나 그것은 또 다른 이야기입니다.
원하는 것을 달성하는 다른 방법이 있습니다.
find a -not -path "*/b*" -type f -delete
기억하기 쉬울 수도 있고 아닐 수도 있습니다.
이 명령은 여전히 디렉토리로 내려 가서 거부 할 수 b
있도록 모든 단일 파일을 처리 -not
합니다. 디렉토리 b
가 큰 경우 성능 문제 일 수 있습니다 .
-path
와 다르게 작동합니다 -name
. 전체 경로와 일치하는 -name
동안 파일 또는 디렉토리의 이름과 만 일치 -path
합니다. 예를 들어 경로를 관찰하십시오 /home/lesmana/foo/bar
. -name -bar
이름이이므로 일치합니다 bar
. -path "*/foo*"
문자열 /foo
이 경로에 있기 때문에 일치 합니다. -path
사용하기 전에 이해해야 할 몇 가지 복잡한 사항이 있습니다 find
자세한 내용 은 맨 페이지 를 참조하십시오.
이것이 100 % 완전하지 않다는 것을 명심하십시오. "거짓 긍정적"일 가능성이 있습니다. 명령이 위에 작성되는 방식은 이름이 시작하는 상위 디렉토리가있는 파일 b
(긍정) 을 건너 뜁니다 . 그러나 b
트리의 위치에 관계없이 이름이 시작하는 파일은 건너 뜁니다 (거짓 긍정적). 보다 나은 표현을 작성하면 문제를 해결할 수 있습니다 "*/b*"
. 그것은 독자를위한 연습으로 남아 있습니다.
난 당신이 사용한다고 가정 a
하고 b
더 같은 자리 표시와 실제 이름은로 allosaurus
와 brachiosaurus
. 당신이 넣으면 brachiosaurus
대신에 b
다음 오탐 (false positive)의 양이 크게 감소합니다.
적어도 오탐 (false positive)이 될 것입니다 하지 가 비극적으로하지 수 있도록, 삭제. 또한, 먼저 명령을 실행하지 않고 오 탐지 여부를 확인 -delete
하고 (암시 적을 배치해야 함 -depth
) 출력을 검사 할 수 있습니다.
find a -not -path "*/b*" -type f -depth
a
제외하고 모든 것을 어떻게 포함a/b
합니까?