GNU find -not과 GNU find -prune -o -print의 차이점

GNU find -not과 GNU find -prune -o -print의 차이점

[조건]을 제외하고 vim에서 모든 파일을 여는 방법에 대한 답변은 다음과 같습니다.

https://unix.stackexchange.com/a/149356/98426

비슷한 대답을 했습니다.

find . \( -name '.?*' -prune \) -o -type f -print

(내 질문은 vim과 관련이 없기 때문에 답변을 수정했습니다)

부정적인 조건은 이스케이프된 괄호로 묶입니다. 그러나 내 테스트 파일에는 다음과 같은 내용이 있습니다.

find . -type f -not -name '^.*'

동일한 결과를 생성하지만 읽고 쓰기가 더 쉽습니다. -not 방법은 -prune 방법과 동일하며 .-not 및 -prune -o -print 방법이 다른 결과를 생성하는 극단적인 경우가 무엇인지 궁금합니다.

Findutils의 정보 페이지는 다음과 같습니다.

-아니요표현: expr이 거짓이면 참

-prune: 파일이 디렉터리인 경우 해당 디렉터리를 입력하지 마세요. (그리고 실제로 최상위 일치 디렉토리를 제외하기 위해 -o -print의 필요성을 추가로 설명하기 위해)

-not은 테스트이고 -prune은 작업이므로 이런 식으로 비교하기는 어려워 보이지만, 나에게는 그것들이 상호 교환 가능합니다(-o -print가 -prune을 따르는 한).

답변1

-not먼저, 이는 표준 연산자와 동등한 GNU 확장이라는 점에 유의하세요 !. 이에 비해 장점이 거의 없습니다 !.

술어는 -prune항상 다음과 같이 평가됩니다.진짜그리고 디렉토리 트리가 이동하는 방식에 영향을 줍니다 find. 실행하는 파일이 -prune다음 유형인 경우목차(아마도 -L//를 사용하여 심볼릭 링크를 확인한 후에 결정될 것임) 그런 다음에는 해당 항목으로 내려가지 않을 것입니다.-H-followfind

따라서 -name 'pattern' -prune(의 약어 -name 'pattern' -a -prune)는 다음과 같습니다. -name 'pattern'이름이 일치하는 디렉토리만 다음 pattern과 같습니다.손질된, 그러면 find그들에게는 그런 일이 일어나지 않을 것입니다.

-name '.?*'.이름이 1로 시작하는 파일과 일치합니다.특징(정의는 현재 로케일에 따라 다름) 뒤에 0 이상이 옵니다.수치. 따라서 실제로는 .하나 이상의 문자와 그 뒤에 오는 문자와 일치합니다( .시작 디렉터리가 잘리는 것을 방지하기 위해).

따라서 이는 숨겨진 파일과 일치하지만 주의할 점은 이름이 다음과 같이 모두 구성된 파일만 일치한다는 것입니다.수치즉, 현재 로케일의 유효한 텍스트입니다(적어도 GNU 구현의 경우).

그래서 여기,

find . \( -name '.?*' -a -prune \) -o -type f -a -print

어느 것이 동일합니까?

find . -name '.?*' -prune -o -type f -print

AND( -a묵시적)가 OR()보다 우선하기 때문입니다 -o.

다음 파일을 찾으세요정기적인(심볼릭 링크, 디렉터리, fifos, 장치 등 없음) 숨김이 없고 숨겨진 디렉터리에 있지 않습니다(모든 파일 경로가 로케일에서 유효한 텍스트라고 가정).

find . -type f -not -name '^.*'

또는 그에 상응하는 표준:

find . -type f ! -name '^.*'

로 끝나지 않는 이름을 찾습니다 ^..

find . -type f ! -name '.*'

이름이 로 시작하지 않는 일반 파일은 발견되지만 .숨겨진 디렉터리에 있는 파일은 계속 보고됩니다.

find . -type f ! -path '*/.*'

숨겨진 파일과 숨겨진 디렉터리의 파일은 무시되지만 find그 안의 모든 파일을 건너뛰기 위해 숨겨진 디렉터리(모든 수준 깊이)로 계속 드롭다운하므로 를 사용하는 것보다 낫습니다 -prune.

답변2

-prunein 술어는 find검색 트리의 분기를 삭제합니다. 따라서 -prune 질문의 첫 번째 명령과 함께 as를 사용하면 디렉터리에 숨겨진 이름을 가진 파일이 없는 경우 두 번째 명령과 동일한 결과가 제공됩니다.

예:

$ tree -a
.
|-- .hiddendir
|   `-- file
`-- dir
    `-- file

2 directories, 2 files
$ find . \( -name '.?*' -prune \) -o -type f -print
./dir/file
$ find . -type f ! -name '.*'
./dir/file
./.hiddendir/file

( -name당신이 말이 안 되는 정규식을 사용하고 있는 것 같아서 여기서 테스트를 수정했고, !비표준 대신 그것을 사용했습니다 -not).

보시다시피 이름이 .hiddendir와일드카드 패턴과 일치하므로 .?*첫 번째 명령을 사용하면 검색 트리에서 제거되고 file그 아래의 파일은 찾을 수 없습니다.

두 번째 명령에서는 .hiddendir디렉터리가 검색 트리에서 제거되지 않으므로 디렉터리 file에 있는 파일을 찾을 수 있습니다.

관련 정보