특정 디렉터리를 제외하지 못했습니다.

특정 디렉터리를 제외하지 못했습니다.

.git/명령만 사용하여 find디렉터리 내부의 파일을 제외한 모든 파일을 나열 하고 싶습니다 .

나는 이것을 시도했습니다 :

$ find . -path .git -prune -type f
$

(내가 가지고 있는 2개가 아닌) 0개의 파일을 반환했기 때문에 다음을 시도했습니다.

$  find . -not -path .git -type f | grep -c '\.git'
1770
$

왜 이것이 효과가 없는지 이해가 되지 않습니다. 도와주실 수 있나요?

EDIT0: @icarus 덕분에 경로가 앞에 와야 한다는 것을 알았고 그 때문에 연산자가 ./누락되었습니다. 이 명령은 작동했습니다.OR

$ find . -path ./.git -prune -o -type f | grep '\.git'
./.git
./.gitignore
$

EDIT1: 다른 명령이 작동하지 않는 이유는 무엇입니까?

$ find . -not -path ./.git -a -type f | grep -c '\.git'
1770
$

EDIT2: 마지막 질문: -prune술어가 -o -print다음 명령의 결과를 인쇄할 필요가 없는 이유는 무엇입니까 ./.git?./.gitignore

$ find . -name ".git*" -prune | grep git
./.git
./.gitignore
$ find . -name ".git*" -prune -o -print | grep -c git
0

편집 3: 감사합니다 @rastafile:

$ find . -name ".git*" -prune | grep git
./.git
./.gitignore
$ find . -name ".git*" -prune -print | grep git
./.git
./.gitignore
$ find . -name ".git*" -prune -o -print | grep git
$

GNU find 조건자는 앞의 표현식이 true일 때 -prune암시적으로 호출되는 것처럼 보입니다.-print

표현식에 -prune을 제외한 작업이 없으면 표현식이 true인 모든 파일에 대해 -print가 수행됩니다.

결론: 나에게 필요한 명령은 다음과 같습니다.

$ find . -name ".git*" -prune -o -type f -print

다들 감사 해요.

답변1

-path와 사이에는 큰 차이가 있습니다 -name. 둘은 전혀 유사하지 않습니다. "이름"은 마지막 부분만 보고, "경로"는 전체 슬래시 체인을 봅니다. "파일 이름" 또는 "경로 이름"의 의미는 항상 논쟁의 여지가 있습니다. 그러나 여기서 요점은 명확하고 중요합니다.

이것은 작동합니다 (당신이 말했듯이):

find . -path ./.git -prune -o -type f 

로 시작 .하면 기본 gitdir이 발견되고 정리됩니다. 다른 파일은 존재하지 않으므로 ./.git다른 모든 사람의 () 유형 파일을 확인합니다.-o


마지막 예:

find . -not -path ./.git -a -type f 

작동하지 않습니다. 단지 모든 것을 찾습니다.문서.

피하고 싶다면 -prune일치해야합니다내부 품목:

-path './.git/*'

Icarus의 -name/-prune 조합에 동의하지만 수정 사항이 있습니다.

]# find . -name .git -prune -o -type f -name '*git*' -print   
./.git.filehidd
./gitfile

여기에는 괄호가 필요하지 않습니다.

-name '*git*'테스트/출력 감소를 위해 추가되었습니다 .

-print마지막 명시적 작업은 다음을 트리밍하여 인쇄를 억제합니다.

]# find . -name .git -prune                                 
./.git
./10/.git

괄호에 대해 잘 모르겠습니다. man find(GNU)을 찾아보니 이에 대한 멋진 세부 정보가 나와 있습니다.

 find . -name .snapshot -prune -o \( \! -name *~ -print0 \)

.... 하지만 .snapshot이라는 이름의 파일과 디렉터리(및 그 안의 모든 내용)는 생략합니다. 또한 이름이 ~로 끝나는 파일이나 디렉터리를 생략하지만 내용은 생략합니다. 이 구조는 -prune -o \( ... -print0 \) 매우 일반적입니다. 여기서의 아이디어는 -prune 앞의 표현이 정리할 내용과 일치한다는 것입니다. 그러나 -prune 작업 자체는 true를 반환하므로 다음 -o는 정리되지 않은 디렉터리에 대해서만 오른쪽이 평가되도록 보장합니다. 정리된 디렉터리의 내용은 액세스조차 되지 않으므로 해당 내용은 관련이 없습니다. -o의 오른쪽 표현식은 다음과 같습니다.괄호는 단지 명확성을 위한 것입니다.. -print0 작업은 -prune이 적용되지 않은 콘텐츠에서만 작동한다는 점을 강조합니다. 테스트 간의 기본 "and" 조건부 바인딩으로 인해-o보다 가까움, 이는 어쨌든 기본값이지만 대괄호는 무슨 일이 일어나고 있는지 보여주는 데 도움이 됩니다.

저에게는 다음과 같은 방법으로 명확성이 향상되었습니다.

find . ( -name .snapshot -prune ) -o ( ! -name '*~' -print0 )

그러나 이것은 작동하지 않습니다!

여기서 -a이와 같은 것을 생략하면 -o명확성을 위해 괄호도 생략할 수 있을 정도로 눈에 띕니다.


(쉘도 괄호를 좋아하기 때문에,당신은 그것을 인용해야합니다. 그러나 이제 명확성은 안녕입니다. )

1) find . -name .snapshot -prune -o \( \! -name *~ -print0 \)

2) find . -name .snapshot -prune -o ! -name '*~' -print0 

인용되지 않은 것은 !작동하지만(내 것은 그렇습니다) 인용되지 않은 것은 *작동하지 않습니다.


따라서 디렉토리를 제외한 파일(모든 유형)을 찾으려면 다음을 수행하십시오 .git.

find -name '.git' -type d -prune -o -print 

(상관하지 않으면 type-d도 생략할 수 있습니다... Camille's를 참조하세요.논평...밖은 정글이야거기, 작은 것으로 확인됨프로그래밍 언어: 뭐가 필요하세요)

답변2

find에서 조인 항목의 기본 작업은 and다음과 같습니다.

find / -user root -name fred

루트에 속하고 이름이 fred인 파일을 찾는 것을 나타냅니다. 작업 을 수행하고 or이름이 ".git"인 경우 잘라내거나 파일인 경우 나열하려고 합니다.

find . \( -name .git -prune \) -o -type f

-name. 대신 . 을 사용하고 있습니다 -path. 시작 위치를 지정하면 .최상위 디렉토리가 호출 .git됩니다 ../.git-path

그래서

find . -path .git -prune -type f

-path .git모든 파일이 일치하지 않고 시작되기 때문에 아무것도 제공하지 않습니다../

find . -not -path .git -type f

각 파일을 제공하면 모든 것이 일치하므로 -not -path .git유일한 필터링은 -type f출력을 파일로 제한하는 것입니다.

관련 정보