![find 명령에서 하나의 특정 경로를 제외한 모든 하위 디렉터리 제외](https://linux55.com/image/31859/find%20%EB%AA%85%EB%A0%B9%EC%97%90%EC%84%9C%20%ED%95%98%EB%82%98%EC%9D%98%20%ED%8A%B9%EC%A0%95%20%EA%B2%BD%EB%A1%9C%EB%A5%BC%20%EC%A0%9C%EC%99%B8%ED%95%9C%20%EB%AA%A8%EB%93%A0%20%ED%95%98%EC%9C%84%20%EB%94%94%EB%A0%89%ED%84%B0%EB%A6%AC%20%EC%A0%9C%EC%99%B8.png)
find
특정 디렉터리 경로를 무시하고 현재 하위 디렉터리에서 특정 확장자를 가진 모든 파일을 검색하는 명령을 사용합니다 .
find -L . \( -wholename "*/ignoredPath" -o -wholename "*/ignoredPath2" \) -prune -o -name "*.ext"
이것은 잘 작동하지만 이제 정확한 하위 디렉터리 중 하나를 제외한 다른 경로를 무시하고 싶습니다. 무시할 모든 하위 디렉터리를 나열하지 않고 이 작업을 수행하려면 어떻게 해야 합니까?
예를 들어 다음과 같은 폴더 트리가 있는 경우:
*/base/pathToIgnore1
*/base/subdir/requiredPath
*/base/subdir/pathToIgnore2
*/base/subdir/pathToIgnore3
*/base/pathToIgnore4
경로를 제외한 모든 하위 디렉터리를 find
무시하는 명령을 어떻게 작성할 수 있습니까 ?base
*/base/subdir/requiredPath
나는 다음과 같은 것을 시도했습니다
find -L . \( -wholename "*/ignoredPath" -o -wholename "*/ignoredPath2" -o \( -wholename "*/base" -a ! -wholename "*/base/subdir/requiredPath" \) \) -prune -o -name "*.ext"
하지만 작동하지 않으며 모든 base
하위 디렉터리가 무시됩니다.
답변1
find -L . \
\( -type d \
\( -path "*/ignore" -o -path "*/indeed" -o \
\( -path "*/subdir/*" ! -path "*/subdir/save" \
\) \
\) \
\) \
-prune -o -print
추가 필터(예 -name "*.ext"
: )를 원할 경우 필터를 앞에 배치해야 합니다 -print
. 마지막 부분은 이렇습니다
-prune -o \( -name "*.ext" \) -print
쓰기 쉽고 읽기 쉽도록 이름을 변경했습니다. 로 시작하는 이름은 i
무시됩니다. s
로 시작하는 이름이 표시됩니다. 로 끝나는 이름은 file
파일입니다.
내 나무는 다음과 같습니다
$ find -printf "%y %p\n"
d .
d ./base
d ./base/subdir
d ./base/subdir/inform
f ./base/subdir/inform/imagefile
d ./base/subdir/isolate
f ./base/subdir/isolate/individualfile
f ./base/subdir/whatwhatinthefile
d ./base/subdir/save
f ./base/subdir/save/soundfile
f ./base/superfile
d ./base/indeed
f ./base/indeed/itemfile
d ./base/show
f ./base/show/startfile
d ./base/ignore
f ./base/ignore/importantfile
위 명령의 출력:
.
./base
./base/subdir
./base/subdir/whatwhatinthefile
./base/subdir/save
./base/subdir/save/soundfile
./base/superfile
./base/show
./base/show/startfile
whatwhatinthefile
에서 base/subdir
이러한 파일을 원하지 않으면 명시적 으로 base/subdir
제외해야 합니다. 시도해봤는데 명령줄이 너무 보기 흉해졌습니다.
사용 사례에 따라 다음과 같이 셸 함수를 정의하는 것이 더 쉬울 수 있습니다.
contrivedfind() {
find -L . \
\( -type d \
\( -path "*/ignore" -o -path "*/indeed" -o -path "*/subdir" \
\) \
\) \
-prune -o -print
find -L ./base/subdir/save
}
이제 출력은 다음과 같습니다.
.
./base
./base/superfile
./base/show
./base/show/startfile
./base/subdir/save
./base/subdir/save/soundfile
이전과 유일한 차이점은 ./base/subdir
항목이 없다는 것입니다. 그러나 어쨌든 파일을 필터링하고 싶기 때문에 그것이 중요하지 않다고 생각합니다.
이전과 마찬가지로 -print
첫 번째 필터 앞에 추가 필터를 배치 해야 하며 find
, 이번에는 두 번째 필터의 끝에도 배치해야 합니다 find
.
답변2
*/base
자체적으로 일치하는 것을 방지해야 합니다 .
편집 1:
find -L . -type d \
\( -wholename "*/ignoredPath" -o -wholename "*/ignoredPath2" -o \
\( -wholename "*/base/*" -a \
\( ! -wholename "*/base/subdir" -a ! -wholename "*/base/subdir/*" \) \) -o \
\( -wholename "*/base/subdir/*" -a \
\( ! -wholename "*/base/subdir/requiredPath" -a ! -wholename "*/base/subdir/requiredPath/*" \) \) \) \
-prune -o -print
이는 약간 까다롭습니다. subdir2
존재하지 않을 수 있는 디렉터리가 실수로 일치하는 것을 방지합니다. 하지만 당신은 결코 알지 못합니다...:-)