find의 prune's -path에는 와일드카드가 포함되어 있지 않습니다.

find의 prune's -path에는 와일드카드가 포함되어 있지 않습니다.

검색 트리에서 특정 디렉토리를 제외하고 싶습니다. .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/b‌​ambi.txt | head -n50 | xargs ls.

또한 다음 경로에서만 검색하고 싶습니다.*/*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt

도와주세요. 내가 뭐 잘못 했어요?

답변1

첫 번째 문제는 인용되지 않은 glob( )이 있다는 것입니다 *. 이러한 모든 경로는 작은따옴표로 묶어야 합니다(예: ) '*/*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt'. 이렇게 하면 쉘이 와일드카드 문자를 전달하기 전에 확장하는 것을 방지할 수 있습니다 find.

-prune다음으로, 기본 검색 하위 표현식 앞에 표시할 하위 표현식이 필요합니다 . 그런데 모든 이름을 다음과 같은 복합 표현식으로 결합할 수 있습니다 -prune.

find \( \( -name '*foo*' -o -name '*bar*' \) -a -prune \) -o \( -name baz -a -print \)

이는 해당 이름을 포함하거나 포함하는 baz파일/디렉터리를 제외하면서 지정된 파일을 찾고 싶다는 것을 의미합니다.foobar

몇 가지 참고사항:

  • 나는 (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/b‌​ambi.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/b‌​ambi.txt:

find -L /students/projects/myname \
    -type d '(' -name '.aaa' -o -name '*rc*' ')' -prune -o \
    -path '*/*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt' -print

이는bambi.txt

/students/projects/myname/*/*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt

명령의 패턴에 대한 참조를 참고하세요 find. 따옴표가 없으면 쉘은 를 호출하기 전에 패턴을 경로 이름 목록으로 확장하려고 시도하며 find이로 인해 혼란이 발생 find하거나 일부 쉘에서는 오류가 발생할 수 있습니다.

관련 정보