find
특정 파일 세트의 크기를 나열하기 위해 명령을 사용하려고 하는데 출력이 나오지 않습니다. 내가 사용하는 명령은 다음과 같습니다
find POD -type f -name *.mp3 -or -name *.ogg -ls
출력이 생성되지 않습니다. 하는 동안:
find POD -type f -name *.mp3 -or -name *.ogg
출력이 생성되면 다음 작업도 시도했습니다.
-printf "%p %k KB\n"
-exec ls -ls '{}' \;
-print0
그러나 이들 모두는 출력을 제공하지 않습니다. 다음과 같은 다른 표현으로 이러한 작업을 사용할 때:
find . -maxdepth 1 -type f -printf "%p %k KB\n"
나는 또한 예상되는 결과를 얻습니다. 문제가 무엇인지 아는 사람이 있습니까? 나는 뛰고있어:
Linux irimi 3.10.37-1-MANJARO #1 SMP Mon Apr 14 20:56:29 UTC 2014 x86_64 GNU/Linux
일명 최신 Manjaro Linux 배포판입니다. 내가 사용하는 쉘은 /bin/bash
version 입니다 4.3.8(1)-release
.
SHELLOPTS
내 환경 변수 의 내용은 다음과 같습니다.
braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
내 BASHOPTS
환경 변수는 다음과 같습니다
cdspell:checkwinsize:cmdhist:complete_fullquote:dotglob:expand_aliases:extglob:extquote:force_fignore:histappend:hostcomplete:interactive_comments:nocaseglob:progcomp:promptvars:sourcepath
이 문제를 디버깅하는 데 도움을 주시면 매우 감사하겠습니다.
답변1
함정이 있습니다및/또는에 키워드가 있습니다 find
. or
작업( -ls
예제에서는)을 포함하여 다음의 모든 매개변수에 적용됩니다. and
없는 or
(또는 첨부된 and
) 표현식은 읽기 순서대로 평가되며 최종 중지는 false입니다. .implicit ()
따라서 명령의 find POD -type f -name *.mp3 -or -name *.ogg -ls
의미는 다음과 같습니다.
- 파일 검색(POD 디렉터리에서 시작) --- 파일을 찾을 수 없는 경우: 중지
- else (파일 발견) 패턴 일치 확인
*.mp3
--- 패턴이 일치하는 경우: 중지하세요! (OR
여기서 적용되기 때문에 이전 명령이 실패한 경우에만 적용됩니다(단, 이전 명령만 적용되고 이전 명령 그룹은 적용되지 않음).
그리고 명령줄에 실행 문( -ls
, -exec
, -print
....)을 추가하기 때문에 암시적 명령이 없으므로 -print
1) 1)의 모든 조건이 true(파일 및 패턴 일치)인 경우 실행할 것이 없습니다. 마지막 항목을 제거하면 각 조건 분기 끝에 -ls
암시적으로 배포됩니다 .-print
- else if 패턴이 일치하지 않으면 패턴과 일치하는 항목(파일/디렉토리)
*.ogg
을 검색하여 나열합니다(-ls
조건 명령이 아니며 이전 명령/테스트 "패턴이 true인 경우에만 실행됩니다*.ogg
. 그러나 1 때문에). 2) NON mp3 파일에 대해서만 평가됩니다. 파일이 없으면.ogg
아무것도 표시되지 않습니다.
솔루션 1 각 논리적 분기에서 실행 명령을 반복합니다.
find POD -type f -name "*.mp3" -ls -or -name "*.ogg" -ls
솔루션 2(쉘 보호) 괄호 추가
find POD -type f \( -name "*.mp3" -ls -or -name "*.ogg" \) -ls
메모 현재 디렉토리에서 쉘 패턴 평가를 방지하려면 패턴을 보호해야 합니다.
답변2
내 생각에는 평가 순서(명시적인 우선순위 부족) 때문인 것 같습니다.
-name '*.mp3' -o -name '*.ogg' -ls
그런 다음 -name '*.ogg'
false로 평가 되면 ls
작업이 실행되지 않습니다. 괄호를 사용하여 OR 표현식을 그룹화하면 원하는 동작을 얻을 수 있습니다. 예를 들어 다음과 같습니다.
$ ls tests
file1.mp3 file2.mp3 file3.mp3
그 다음에
$ find tests \( -name '*.mp3' -o -name '*.ogg' \) -print
tests/file3.mp3
tests/file1.mp3
tests/file2.mp3
반면
$ find tests -name '*.mp3' -o -name '*.ogg' -print
출력이 생성되지 않습니다. 참고하세요
$ find tests -name '*.mp3' -o -name '*.ogg'
암묵적으로 다음과 같이 취급되기 때문에 특별한 경우입니다.
$ find tests \( -name '*.mp3' -o -name '*.ogg' \) -print
find
또한 쉘이 확장되는 것을 방지하기 위해 명령 에서 쉘 글로브를 인용하거나 이스케이프하는 것이 좋습니다 . NON-BUGS
find 맨페이지 섹션을 참조하십시오.