찾은 콘텐츠가 현재 디렉터리에 있으면 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
인 파일은 일치 해야 하므로 n
FreeBSD 또는 파생 제품(macOS, DragonFly BSD...)에서는 다음과 같습니다.
find ~+ -depth 1 -type f -exec printf 'File: %s' {} ';' -o -print
여기서는 -exec printf
GNU 특정 -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=C
GNU에서는 이를 요구하며 유효한 문자를 형성하지 않는 바이트 시퀀스가 포함된 경로 구성 요소를 일치시킬 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