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
전체 표현 세트(용어의 일반적인 의미에서,즉디렉토리 등 포함), 왼쪽부터 시작:
-type d
현재 파일이 디렉터리이면 true로 평가되고, 그렇지 않으면 false로 평가됩니다.-exec ...
앞의 표현식이 true이면 현재 파일이 디렉터리인지 여부를 평가합니다. 평가에는 현재 파일을 인수로 사용하여 실행하는 작업이 포함되며sh -c 'printf "%s/\n" "$0"'
결과는 상태 0으로 종료되면 true이고, 그렇지 않으면 false입니다.sh
-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의 명령줄은 보기 흉하지만 쿼리는 훌륭합니다!