이름에 3자 이상이 포함된 모든 PDF를 찾습니다.

이름에 3자 이상이 포함된 모든 PDF를 찾습니다.

이름(확장자 제외)이 3보다 큰 PDF 파일을 찾고 싶습니다.

$ find ~ -iregex ".{3,}/.pdf"

아무것도 반환하지 않지만

$ find ~ -iregex ".+/.pdf"

일하다.

이 변형을 활성화하는 방법은 무엇입니까 {3,}?

답변1

여기서는 표준 와일드카드를 사용하는 것이 더 쉽습니다.

find ~ -name '*???.[pP][dD][fF]'

또는 일부 구현을 통해 find(지원하는 구현 -regex도 지원 -iname):

find ~ -iname '*???.pdf'

대신 문자 수에 관계없이 사용 가능한 위치 3로 되돌리는 것이 좋습니다 (참조-iregex@Stephen Kitt의 답변) 또는 다음을 사용하거나 glob할 수 zsh있습니다 ksh93.

  • zsh:

    set -o extendedglob # best in ~/.zshrc
    printf '%s\n' ~/**/?(#c3,).(#i)pdf(D)
    

    ( (D)숨겨진 파일과 다음과 같은 숨겨진 디렉터리에 있는 파일을 생각해 보세요 find)

    • (#cx,y)zsh정규식에 해당하는 와일드카드 입니다 .{x,y}
    • (#i)대소문자를 구분하지 않는 경우
    • ?단일 문자 표준 와일드카드(예: regexp .)
    • **/: 모든 레벨 하위 디렉토리(레벨 0 포함)
  • ksh93:

    FIGNORE='@(.|..)' # to consider hidden files
    set -o globstar
    printf '%s\n' **/{3,}(?).~(i:pdf)
    
    • @(x|y): regexp와 유사한 확장 ksh 와일드카드 연산자입니다 (x|y).
    • FIGNORE: 전역적으로 무시되는 파일을 제어하는 ​​특수 변수입니다. 일단 설정되면 숨겨진 파일은 일반적으로 무시되지만 우리는 여전히 존재하는 디렉토리 항목을 무시하려고 합니다 ....
    • {x,y}(z)ksh93regexp 와 동일 합니다 z{x,y}.
    • ~(i:...): 대소문자를 구분하지 않는 일치입니다.

Glob에는 정렬된 목록을 얻을 수 있고(glob 한정자를 사용하여 find정렬을 비활성화하거나 다른 정렬 기준을 사용할 수 있음) 파일 이름에 유효한 형식을 형성하지 않는 바이트 시퀀스가 ​​포함된 경우에도 몇 가지 추가 이점이 있습니다. 문자 작업(예: UTF-8 문자 세트를 사용하는 로케일에서 이 방법은 a를 문자가 아닌 것으로 보고하지 못하므로 정규 표현식이나 와일드카드 또는 GNU와 일치하지 않습니다.zshoNfind$'St\xE9phane Chazelas - CV.pdf\xE9.?*find

답변2

당신이 GNU를 사용하고 있다고 가정합니다 ( GNU의 확장 find이므로 아마도 그럴 것입니다 ).-iregexPOSIXfind), 기본값은 Emacs 정규식으로 설정되어 -regex있으며 -iregex이는 인식하지 못합니다 {3,}. 또한 이 옵션을 사용하여 다른 유형의 정규식을 지정해야 하며 -regextype전체 경로와 일치하도록 정규식을 조정해야 합니다.

find ~ -regextype posix-extended -iregex '.*/[^/]{3,}.pdf'

.또한 "."과 일치하도록 이스케이프해야 합니다 . 문자 대신:

find ~ -regextype posix-extended -iregex '.*/[^/]{3,}\.pdf'

"/"가 아닌 문자 세 개만 고려하므로 정규식을 단순화할 수 있습니다.

find ~ -regextype posix-extended -iregex '.*[^/]{3}\.pdf'

완전성을 기하기 위해 FreeBSD 또는 NetBSD ( 귀하의 것이 아니지만 find지원되는 또 다른 구현 )의 경우 다음과 같이 작성할 수 있습니다.-iregex.+-E

find ~ -iregex '.*[^/]\{3\}\.pdf'

또는:

find -E ~ -iregex '.*[^/]{3}\.pdf'

아니 -E, 그건기본 정규식(예 grep: ) 및-E 확장 정규식(그림 grep -E).

ast-open 사용 find:

find ~ -iregex '.*[^/]{3}\.pdf'

(이것은 기본적으로 확장된 정규식입니다.)

답변3

PDF인지 어떻게 알 수 있나요?

당신이 묻지 않는 한 당신은하지 않을 것입니다. 물론 제가 현학적으로 말하지만 당신은 묻지 않았어요파일 .pdf이름에는 다음이 포함됩니다.. .pdf파일 이름에 문자가 있기 때문에PDF 파일로 만들지 마세요.

사실, 이것에 대해 계속 현학적으로 생각해보자: 파일 이름의 마지막 네 글자가 이면 .pdf,이름에는 항상 3자 이상의 문자가 포함됩니다..

그러니 이렇게 해라잘못된 방법, 다음과 같이 말할 수도 있습니다.

$ find . -type f -name "*???.pdf"
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Setup_MagicISO.exe.pdf

두 번째도 보셨나요? 실제로 실행 가능한 파일입니다. (알고 있어요, 이름을 바꿨어요.) 그리고 PDF 파일도 잃어버렸어요맹세할 수 있다문서 디렉토리에 위치합니다...

$ ls Documents
McLaren 720s Coupe:Order Summary.pdf
Pioneer Premier DEH-P490IB CD Install Manual.PDF
Setup_MagicISO.exe.pdf

따라서 -iname파일을 찾을 수 있지만 PDF가 아닌 파일은 여전히 ​​나타납니다.

우리를진짜이 경우 해야 할 일은 파일의 내용을 확인하는 것입니다.매직넘버file명령을 사용하십시오 . 옵션 출력MIME 유형, 구문 분석하기가 더 쉽습니다. 그러면 쿼리가 find간단해집니다 -name "???*".

$ find . -type f -name "???*" -print0|xargs -0 file --mime
./.bash_history:                                              text/plain; charset=us-ascii
./.bash_logout:                                               text/plain; charset=us-ascii
./.bashrc:                                                    text/plain; charset=us-ascii
./.profile:                                                   text/plain; charset=us-ascii
./Documents/McLaren 720s Coupe:Order Summary.pdf:             application/pdf; charset=binary
./Documents/Pioneer Premier DEH-P490IB CD Install Manual.PDF: application/pdf; charset=binary
./Documents/Setup_MagicISO.exe.pdf:                           application/x-dosexec; charset=binary
./Downloads/Setup_MagicISO.exe:                               application/x-dosexec; charset=binary
./Downloads/WindowsUpdate.diagcab:                            application/vnd.ms-cab-compressed; charset=binary

콜론 구분 기호를 사용하여 MIME 유형을 찾은 다음 application/pdf해당 부분을 0으로 만들고 결과를 인쇄해 보겠습니다. 내 파일 중 하나에는 이름에 콜론이 있으므로 그냥 물어볼 수는 없습니다 awk ($2==":"){print $1}.

$ find . -type f -name "???*" -print0|xargs -0 file --mime|awk -F: '($NF~"application/pdf"){OFS=":";$NF="";print}'|sed s/:$//
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Pioneer Premier DEH-P490IB CD Install Manual.PDF

a이제 다음과 같은 이름의 PDF 파일을 포함시켜 보겠습니다 abc.

$ mkdir Documents/other
$ cp -a Documents/McLaren\ 720s\ Coupe\:Order\ Summary.pdf Documents/other/a
$ cp -a Documents/Pioneer\ Premier\ DEH-P490IB\ CD\ Install\ Manual.PDF  Documents/other/abc
$ find . -type f -name "???*" -print0|xargs -0 file --mime|awk -F: '($NF~"application/pdf"){OFS=":";$NF="";print}'|sed s/:$//
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Pioneer Premier DEH-P490IB CD Install Manual.PDF
./Documents/other/abc

그게 다야. 너무 현학적이라고 비난받을 수도 있다는 걸 알지만,내 작품에수천 개의 NFS 볼륨과 이름이 잘못된 다양한 파일을 접하면서 더 많은 사람들이 현명해졌으면 좋겠습니다.

추가하도록 편집됨: 실제 세계에서는 이를 활용하여 해당 인덱스를 스레딩하는 대신 해당 인덱스를 읽는 대신 updatedb검색 가능한 파일 인덱스를 구축하고 싶을 수 있습니다 . 그러나 이것은 이 질문의 범위를 약간 벗어납니다. 저도 정색으로 썼어요. 내가 왜 그렇게 신경을 쓰는 걸까? 프로젝트의 데이터 디렉토리에서 영화 및 오디오 파일, 특정 유형의 사진 또는 바이너리 실행 파일을 찾고 있을 수 있습니다.locatefindparallelxargs

관련 정보