'찾기'는 조건부 심층 검색을 수행할 수 없습니다.

'찾기'는 조건부 심층 검색을 수행할 수 없습니다.


찾은 콘텐츠가 현재 디렉터리에 있으면 Find에서 조건부 심층 검색을 수행하도록 시도합니다. 파일을 찾은 다음 해당 출력을 언어로 해석하고, 그렇지 않으면 평소대로 출력합니다.

$ find ~+ -maxdepth 1 \( -type f -printf 'File: %p\n' -o  -printf '%p\n' \) -o -mindepth 2 -printf '%p\n'

find: warning: you have specified the -mindepth option after a non-option argument (, but options are not positional (-mindepth affects tests specified before it as well as those specified after it)..

왜 실패하고 그러한 요구 조건을 해결하는 방법은 무엇입니까?

답변1

-maxdepth/ -mindepth(비표준 GNU 확장이지만 현재는 find다른 많은 구현에서 지원됨)은 그렇지 않습니다.상황디렉토리로 내려가는 방법에 영향을 미치는 전역 플래그인 술어 find.

-maxdepth표준 효과는 다음의 조합을 통해 달성할 수 있습니다.-path-prune.

FreeBSDfind-depth n/-n/+깊이가 n/ < /> n인 파일은 일치 해야 하므로 nFreeBSD 또는 파생 제품(macOS, DragonFly BSD...)에서는 다음과 같습니다.

find ~+ -depth 1 -type f -exec printf 'File: %s' {} ';' -o -print

여기서는 -exec printfGNU 특정 -printf.

기술적으로는 printf실패할 수 있으므로 재정의를 -print사용하면 이 문제를 해결할 수 있지만 표시 순서에 영향을 미칩니다. 또는 다음과 같이 변경할 수 있습니다.-exec ... {} +-exec ... {} ';'

find ~+ -depth 1 -type f '(' -exec printf 'File: %s' {} ';' -o -true ')' -o -print

또는:

find ~+ '(' ! -depth 1 -o ! -type f ')' -print -o -exec printf 'File: %s' {} ';'

표준적인 경우에는 -path이를 대신 사용할 수 있습니다(그렇게 간단하지는 않지만).

LC_ALL=C find ~+/. -path '*/./*/*' -print -o \
  -type f -printf 'File: %p\n' -o -print

또는 깊이를 2로 제한하십시오(내 답변의 이전 버전에서와 같이 귀하가 -mindepth 2그렇다고 가정합니다 -maxdepth 2).

LC_ALL=C find ~+/. -path '*/./*/*' -prune -print -o \
  -type f -printf 'File: %p\n' -o -print

(아직 GNU에 특화된 표준은 아닙니다 -printf.)

s의 깊이 0 지점을 표시하기 위해 /.경로에 추가합니다 (그렇지 않으면 $PWD/에 나타나지 않도록 보장됨) .~+find-path

대신 사용할 수 없습니다 -path "$PWD/*/*"(예:제안된 수정사항$PWD), 이는 와일드카드나 백슬래시가 포함된 값에서는 올바르게 작동하지 않기 때문입니다( -path인수가 와일드카드 패턴으로 처리되기 때문입니다).

비교하다:

$ mkdir -p '[1]/2/3/4'
$ touch '[1]/2/3/4/file'
$ cd '[1]'
$ LC_ALL=C find ~+ -path "$PWD/*/*" -print -o -type f -printf 'File: %p\n' -o -print
/tmp/[1]
/tmp/[1]/2
/tmp/[1]/2/3
/tmp/[1]/2/3/4
File: /tmp/[1]/2/3/4/file
$ LC_ALL=C find ~+/. -path '*/./*/*' -print -o -type f -printf 'File: %p\n' -o -print
/tmp/[1]/.
/tmp/[1]/./2
/tmp/[1]/./2/3
/tmp/[1]/./2/3/4
/tmp/[1]/./2/3/4/file

대안은 추가하는 것입니다 . 그러나 일부 구현에서는 추가 후행 비트를 제거하기 //때문에 이식성이 떨어집니다 .find/

파이프를 통해 출력에서 ​​해당 항목을 sed 's:/\./:/:'제거 할 수 있습니다 ././

LC_ALL=CGNU에서는 이를 요구하며 유효한 문자를 형성하지 않는 바이트 시퀀스가 ​​포함된 경로 구성 요소를 일치시킬 find수 없습니다 .*


GNU에는 find파일의 깊이를 명시적으로 일치시키는 조건자가 없지만 해당 -printf조건자는인쇄그 깊이. 따라서 여기에서 File:깊이가 1인 일반 파일에 해당 접두사를 추가하고 몇 가지 후처리를 수행할 수 있습니다.

find . -printf '%d%y,%p\0' | # print depth, type and path
  sed -z 's/^1f,/&File: /' | # add "File: " prefix for regulars at depth 1  
  cut -zd, -f2-            | # remove the depth and type
  tr '\0' '\n'               # NL delimited for user consumption

관련 정보