검색 트리에서 특정 디렉토리를 제외하고 싶습니다. .aaa
현재 디렉터리의 숨겨진 하위 디렉터리입니다. 해당 이름에 aaa_rc_bbb, xxx_rc_xxx
포함된 더 많은 하위 디렉터리를 제외하고 싶습니다. rc
하지만 여전히 무시하지 않고 rc
하위 디렉터리를 포함하는 결과를 제공합니다. *rc*
와일드카드가 작동하지 않는 것과 같습니다 .
find -L /students/projects/myname/ -name .aaa -prune -o -path */*/class_project/*/*/pikachu/*/*/*rc*/ -prune -o -path */*/class_project/*/*/pikachu/*/*/bambi/bambi.txt | head -n50 | xargs ls
.
또한 다음 경로에서만 검색하고 싶습니다.*/*/class_project/*/*/pikachu/*/*/bambi/bambi.txt
도와주세요. 내가 뭐 잘못 했어요?
답변1
첫 번째 문제는 인용되지 않은 glob( )이 있다는 것입니다 *
. 이러한 모든 경로는 작은따옴표로 묶어야 합니다(예: ) '*/*/class_project/*/*/pikachu/*/*/bambi/bambi.txt'
. 이렇게 하면 쉘이 와일드카드 문자를 전달하기 전에 확장하는 것을 방지할 수 있습니다 find
.
-prune
다음으로, 기본 검색 하위 표현식 앞에 표시할 하위 표현식이 필요합니다 . 그런데 모든 이름을 다음과 같은 복합 표현식으로 결합할 수 있습니다 -prune
.
find \( \( -name '*foo*' -o -name '*bar*' \) -a -prune \) -o \( -name baz -a -print \)
이는 해당 이름을 포함하거나 포함하는 baz
파일/디렉터리를 제외하면서 지정된 파일을 찾고 싶다는 것을 의미합니다.foo
bar
몇 가지 참고사항:
- 나는 (AND) 연산자와 괄호에 대해 상당히 자유로우므로
-a
모호함이 없습니다. - 괄호의 목적은 우선 순위를 변경하고 대부분의 다른 표현식 유형과 마찬가지로 이스케이프되어
\
에 전달되기 전에 셸에서 해석되지 않도록 하는 것입니다find
. - 저는 두 개의
-name
테스트를 사용하고 있지만 다른 테스트(예:-path
)는 첫 번째 중첩 괄호 안에 있을 수 있습니다. 테스트와 일치하는 파일/디렉토리는 잘려서 다음 테스트(마지막 괄호 세트)에 적용되지 않습니다. -print
작업을 부분 과 구별하기 위해 명시적 으로 만드는 것이 좋습니다-prune
.
명확성을 위해 보다 일반적인 표현 스타일로 다시 작성하겠습니다.
((name=='*foo*' OR name=='*bar*') AND prune) OR (name==bar AND print)
심지어
if (name=='*foo*' OR name=='*bar*')
prune
else if (name==bar)
print
fi
이제 일반적인 우선순위 규칙과 기본 부울 연산자가 주어지면 -a
예제를 다음과 같이 단순화할 수 있습니다.
find \( -name '*foo*' -o -name '*bar*' \) -prune -o -name baz -print
find
명령을 실행하면 찾은 파일에 대해 작성된 경로가 /
문자로 끝나지 않으므로 -path '*/*/class_project/*/*/pikachu/*/*/*rc*/'
일치가 불가능합니다. 파일 유형을 제한하려면 해당 후행을 제거 /
하고 가능하면 추가 해야 합니다.-type d
목차.
또한 */*
패턴 일치로 포함된 모든 문자열 에는 /
가 포함되어 있습니다 foo/bar/baz
. 여기서 경로는 모두 in 으로 시작하므로 in 은 이미 거기에 있을 것이라는 것을 /students/projects/myname/
알고 있으므로 중복됩니다 ./
*/*
/
귀하의 의도를 올바르게 읽었다면 두 번째 하위 표현식에 대한 테스트를 수행하지 않는 것입니다. 즉, 파일이 잘리지 않으면 인쇄하려고 합니다. 그래서 이것은 다음과 같이 이어진다.
find -L /students/projects/myname/ \
\( \
-name .aaa \
-o -path '*/class_project/*/*/pikachu/*/*/*rc*' \
-o -path '*/class_project/*/*/pikachu/*/*/bambi/bambi.txt' \
\) -prune \
-o -print
답변2
패턴은 -path
슬래시로 끝납니다. find
확인된 경로 이름은 슬래시로 끝나지 않으므로 패턴은 어떤 것과도 일치하지 않습니다.
호출된 디렉터리와 .aaa
해당 이름에 포함된 디렉터리를 정리하려면 다음을 수행하세요.rc
find -L /students/projects/myname \
-type d '(' -name '.aaa' -o -name '*rc*' ')' -prune -o -print
경로만 보기 */*/class_project/*/*/pikachu/*/*/bambi/bambi.txt
:
find -L /students/projects/myname \
-type d '(' -name '.aaa' -o -name '*rc*' ')' -prune -o \
-path '*/*/class_project/*/*/pikachu/*/*/bambi/bambi.txt' -print
이는bambi.txt
/students/projects/myname/*/*/class_project/*/*/pikachu/*/*/bambi/bambi.txt
명령의 패턴에 대한 참조를 참고하세요 find
. 따옴표가 없으면 쉘은 를 호출하기 전에 패턴을 경로 이름 목록으로 확장하려고 시도하며 find
이로 인해 혼란이 발생 find
하거나 일부 쉘에서는 오류가 발생할 수 있습니다.