현재 디렉토리에 있는 오디오 파일(예: MP3)과 현재 디렉토리나 그 아래 어딘가에 존재하는 mp3가 아닌 파일(예: JPEG)에 대해 find를 사용한다고 가정합니다.
이 외에도 우리는 다른 오디오 파일을 포함하는 디렉토리도 있습니다(나를 제외하다예에서는 문자 그대로 파일 검색에서 제외되어야 합니다.
find . \( -type d -name 'exclude_me' -prune \) -o \( -type f -a -iname '*.mp3' -a -print \)
-a
(이 예에서는 꼭 필요한 것은 아니지만 명확성을 위해 일부 중복된 괄호와 기타 연산자를 의도적으로 포함했습니다.)
명시적 옵션 이후 -print
(또한 참조http://mywiki.wooledge.org/UsingFind), 이는 실제로 "exclude_me" 디렉토리의 모든 내용을 생략하고 현재 디렉토리에서 *.mp3 파일만 재귀적으로 나열합니다. 때때로 (항상 그런 것은 아니지만) alias
명령은 한 줄의 코드에 충분할 수 있지만 find
명령에는 매개변수가 필요합니다.끝선.
-iname의 '*.mp3' 매개변수는 다음과 같습니다.앞으로이 -print
경우에는 문제를 해결할 방법이 없는 것 같습니다 alias
.
하지만 단순히 두 가지 옵션을 바꿔서 수학인 것처럼 행동하는 것은 어떨까요?
이와 같이:
find . \( -type d -name 'exclude_me' -prune \) -o \( -type f -a -print -a -iname '*.mp3' \)
.mp3 파일 내에 mp3가 아닌 파일(예: 이미지)이 하나 이상 있어야 한다는 전제 조건을 설정했습니다. 디렉토리 또는 그 하위 디렉토리. 이에 대한 보다 명확한 증거를 제공하기 위해 설립되었습니다.아니요뒤에서는 예상대로 작동합니다. 그들 없이는 상황이 이렇게 될 것입니다.바라보다잘 작동합니다.가지다-iname '*.mp3'
한 줄의 코드에는 다양한 사양이 있지만 해당 사양으로 인해 mp3가 아닌 파일도 나열됩니다. 그러면 -a
연산자가 수학에서처럼 작동하지 않는 이유는 무엇입니까? 여기서 "A + B"는 "B + A"와 동일합니다. 또는 find
전문 용어로:
\( -type f -a -print -a -iname '*.mp3' \)
동일해야합니다
\( -type f -a -iname '*.mp3' -a -print \)
아니면?
원하는 결과를 얻을 수 있는 방법이 있나요?그리고-iname
매개변수를 줄 중간이 아닌 줄 끝 부분에 넣으시겠습니까 ? (추악한 해킹 솔루션 grep -v exclude_me
등은 제외)
답변1
and
or
C, C++, C♯, shell, find 등과 같은 많은 프로그래밍 언어에서는 상호 교환이 불가능합니다 .
그들은 왼쪽에서 오른쪽으로 게으른 평가를 사용합니다. 즉, 왼쪽의 용어가 먼저 평가되고 오른쪽의 용어가 필요한 경우에만 평가됩니다. 따라서 에서는 false and b
답 b
이 항상 틀리기 때문에 평가되지 않습니다. 그러나 두 번째 항이 false라는 것을 아직 발견하지 못했기 때문에 에서는 평가됩니다 b and false
.b
용어가 순수 함수(예: 술어)(부울 값을 반환하고 다른 작업을 수행하지 않음)인 경우에는 아무런 차이가 없지만, 작업을 수행하는 경우(부작용이 있음) 중요합니다.
-print
뭔가를 해보세요. 인쇄되므로 중요합니다.
부작용(예: -print)을 허용하는 모든 시스템은 평가 순서를 정의해야 하며 왼쪽에서 오른쪽으로 가장 쉬울 것입니다.
답변2
그들은 다르다. -print
Primary는 항상 true로 평가되며 현재 경로 이름이 표준 출력에 기록됩니다.
당신이 사용할 때:
\( -type f -a -print -a -iname '*.mp3' \)
발견된 모든 파일은 표준 출력으로 인쇄됩니다.- 인쇄의 기본 동작-iname '*.mp3'
, 표현식이 참인지 거짓인지 에 관계없이 .
당신이 사용할 때:
\( -type f -a -iname '*.mp3' -a -print \)
-print
-iname '*.mp3'
부분은 표현식이 참인 경우에만 도달합니다. 따라서 로 끝나는 파일만 .mp3
인쇄됩니다.
POSIX 정의-a 연산자 찾기처럼:
표현식[-a] 표현식
기본 조합, AND 연산자는 두 개의 기본 연산자를 병치하여 암시적으로 사용하거나 선택적 -a 연산자를 통해 명시적으로 사용합니다.첫 번째 표현식이 false이면 두 번째 표현식을 평가하면 안 됩니다.
이 경우 표현식이 true인 경우 기본적으로 추가되므로 -print
사용할 필요가 없습니다 .-print
표현식이 없으면 -print를 표현식으로 사용해야 합니다. 그렇지 않고 주어진 표현식에 피벗 -exec, -ok 또는 -print가 포함되어 있지 않으면 주어진 표현식은 다음으로 효과적으로 대체됩니다.
(주어진 표현) - 인쇄
하지만 이로 인해나를 제외하다find
일치 하면 -prune
표현식이 true로 평가되기 때문에 출력에 인쇄됩니다 . -print
두 번째 표현식에서는 생략했기 때문에 -print
두 표현식의 끝에 추가됩니다. 다음과 같이 보입니다:
find . \( -type d -name 'exclude_me' -prune \) -print -o \( -type f -a -iname '*.mp3' \) -print
이로 인해나를 제외하다인쇄됩니다.
언제든지 생략할 수 있습니다.나를 제외하다-print
출력에 두 번째 표현식을 명시적으로 추가합니다 . 결과적 -print
으로 두 번째 표현식만 생성됩니다.
find . \( -type d -name 'exclude_me' -prune \) -o \( -type f -a -iname '*.mp3' \) -print
또는 그 뒤에 표현식을 추가 -prune
하고 첫 번째 표현식이 false인지 확인하세요.
find . \( -type d -name 'exclude_me' -prune -a -name . \) -o \( -type f -a -iname '*.mp3' \)
답변3
별칭 대신 쉘 함수를 사용하십시오.
function my_find
{
exclude_dir="$1"
shift
find . \( -type d -name "$exclude_dir" -prune \) -o \( -type f -a -iname "$@" -a -print \)
}