"find -o"와 함께 표현식 및 연산 사용

"find -o"와 함께 표현식 및 연산 사용

find매뉴얼 페이지 에 따르면 OR은 표현식과 함께 사용됩니다.

expr1 -o expr2
              Or; expr2 is not evaluated if expr1 is true.

-print그렇다면 이 예와 같은 작업 에서도 작동하는 이유는 무엇일까요 ?

find . -type d -exec sh -c 'printf "%s/\n" "$0"' {} \; -or -print

(에서디렉토리 다음에 슬래시를 표시하도록 하시겠습니까?).

답변1

행동은표현또한 부작용이 있는 표현이기도 합니다. (POSIX액션은 언급조차 되지 않습니다. )

-exec경우 표현식 값은 실행된 명령의 상태를 반영합니다. 성공하면(종료 코드 0으로 표시됨) 표현식 값은 true이고, 그렇지 않으면 false입니다. 그래서

find . -type d -exec sh -c 'printf "%s/\n" "$0"' {} \; -or -print

현재 디렉터리에서 반복됩니다. 디렉터리 아래에 있는 파일의 경우 실행됩니다 sh( printf디렉토리 뒤에 슬래시가 있음). 다른 모든 경우에는 작업이 실행 find됩니다 print. -or여기서 중요한 값은 s가 아니라 s입니다 .-type d -exec ...-print-type d-exec

더 자세히 말하면 find우선순위 규칙은 다음과 같습니다.

find . -type d -exec sh -c 'printf "%s/\n" "$0"' {} \; -or -print

다음과 같이 더 명시적으로 작성할 수 있습니다.

find . \( -type d -exec sh -c 'printf "%s/\n" "$0"' {} \; \) -or -print

연결 표현식 -or은 다음과 같습니다.

-type d -exec sh -c 'printf "%s/\n" "$0"' {} \;

그리고

-print

전체 표현 세트(용어의 일반적인 의미에서,디렉토리 등 포함), 왼쪽부터 시작:

  1. -type d현재 파일이 디렉터리이면 true로 평가되고, 그렇지 않으면 false로 평가됩니다.

  2. -exec ...앞의 표현식이 true이면 현재 파일이 디렉터리인지 여부를 평가합니다. 평가에는 현재 파일을 인수로 사용하여 실행하는 작업이 포함되며 sh -c 'printf "%s/\n" "$0"'결과는 상태 0으로 종료되면 true이고, 그렇지 않으면 false입니다.sh

  3. -print-type이전 표현식(및 )의 결과가 다음과 같은지 -exec평가합니다 .잘못된,현재 파일이 디렉터리가 아니거나 디렉터리이지만 sh실패했습니다.

답변2

작은 스위치는 -o출력을 완전히 전환합니다. 두 개의 파일("111" 및 "2 2" 포함)과 "test*"와 일치하는 두 개의 인식할 수 없는 디렉터리가 있습니다.

$ find .  -name 'test*'  \(  -exec cat {} \;   -print \) 2>/dev/null
1111 111 11111
./test
2 2 2 2
./test2


$ find .  -name 'test*'  \(  -exec cat {} \;  -o  -print \) 2>/dev/null
./testdir
./testdir2
1111 111 11111
2 2 2 2

첫 번째 항목은 (암시적으로) 성공할 때마다 실행됩니다 -a. 디렉터리의 경우 오류 메시지가 리디렉션되고 -print가 "평가"되지 않습니다. 즉, 논리적 AND 체인이 끊어집니다.-print-exec

두 번째 항목("cat OR print")은 실패 시에만 인쇄됩니다.

자두 예는 인간의 발견 속에 묻혀 있는데, 나는 그것을 이해하는 데 어려움을 겪고 있습니다.

find . -path ./src/emacs -prune -o -print

이러한 AND-OR 목록은 까다롭고 우선순위가 중요하므로 이러한 멋진 목록이 빨리 필요합니다 \(parens\). Find의 명령줄은 보기 흉하지만 쿼리는 훌륭합니다!

관련 정보