이름이 3 자 이상인 모든 PDF 찾기


9

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

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

아무것도 반환하지 않지만

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

공장.

{3,}변형을 어떻게 활성화 할 수 있습니까?


길이는? 파일 이름 길이? 페이지 길이?
이그나시오 바스케스-아 브람스

답변:


18

당신이 GNU 사용하고있는 가정 find(이후, 당신은 아마 -iregex는 GNU에 확장 POSIXfind ) -regex-iregex인식하지 못하는 이맥스 정규 표현식에 기본 {3,}. -regextype옵션을 사용하여 다른 유형의 정규식을 지정해야합니다 . 또한 정규식을 표현식이 전체 경로와 일치한다는 사실로 조정해야합니다.

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

또한 ."."와 일치하도록 탈출해야합니다 . 어떤 캐릭터가 아니라

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

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

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'

(즉석에서 정규 표현식이 확장되었습니다).


20

표준 와일드 카드를 사용하면 더 쉽습니다.

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

또는 일부 find구현 ( -regex지원하는 경우 -iname) :

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

대신 임의의 수의 문자를 사용할 수있는 곳에서 사용 가능한 곳 3으로 되돌 리거나 -iregex( @Stephen Kitt의 답변 참조 ) 사용 zsh하거나 ksh93globs를 사용할 수 있습니다 .

  • zsh:

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

    ( (D)와 같이 숨겨진 디렉토리의 숨겨진 파일 및 파일을 고려하는 것 find)

    • (#cx,y)는 IS 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: globs가 무시할 파일을 제어하는 ​​특수 변수입니다. 설정하면 숨겨진 파일을 무시하는 것이 일반적으로 수행되지 않지만 존재하는 디렉토리 항목 ...디렉토리 항목은 무시하고 싶습니다 .
    • {x,y}(z)ksh93정규 표현식 중의 등가 z{x,y}.
    • ~(i:...): 대소 문자를 구분하지 않습니다.

글롭은 find정렬 목록을 얻는다는 점 zsh에서 ( oN글로브 한정자를 사용하여 정렬을 비활성화 하거나 다른 정렬 기준을 사용할 수 있음) 파일 이름에 유효한 문자를 형성하지 않는 일련의 바이트가 포함되어있는 경우에도 작동 한다는 점에서 추가 이점 이 있습니다. 예는 UTF-8 캐릭터 세트를 사용해 로케일에서, find방법은를보고 실패 $'St\xE9phane Chazelas - CV.pdf가이 같은 \xE9문자는 정규 표현식으로 일치하지 아니되고 .또는 와일드 카드 ?또는 *GNU와 함께 find).


이것이 Bash에 효과가 있습니까? shopt -s dotglob globstar; printf '%s\n' ~/**/*???.[pP][dD][fF]
wjandrea 1

7

PDF인지 어떻게 알 수 있습니까?

요청하지 않으면 안됩니다. 물론, 나는 놀랍지 만, 당신은 그들의 이름 으로 .pdf된 파일에 대해서는 묻지 않았습니다 . 파일 .pdf이름에 문자 가 있다고해서 PDF 파일이되지는 않습니다 .

실제로, 이것에 대해 항상 의논하자 : 파일 이름의 마지막 네 문자가 .pdf이면, 그 이름에는 항상 세 개 이상의 문자가 포함됩니다 .

따라서 이것을 잘못된 방식으로 수행하면 다음과 같이 말할 수 있습니다.

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

두 번째가 보입니까? 실제로는 실행 파일입니다. (나는 이름을 바꿨다.) 또한 내가 맹세 할 수 있는 PDF 가 Documents 디렉토리에 없다.

$ 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 type application/pdf을 찾은 다음 해당 부분을 제로화하고 결과를 인쇄합니다. 내 파일 중 하나에 이름에 콜론이 있습니다. 그래서 그냥 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

이제 다음 aabc같은 이름의 PDF 파일을 포함하도록 고안해 보겠습니다 .

$ 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

그게 다야. 나는 끔찍한 pedantic로 인해 찌그러 질 것임을 알고 있지만 수천 개의 NFS 볼륨을 사용하여 작업 하고 이름이 잘못된 모든 종류의 파일을 찾기 위해 더 많은 사람들이 pedantic이되기를 바랍니다.

추가하기 위해 편집 : 실제 세계에서 updatedb검색 가능한 파일 인덱스를 작성하는 locate대신 find해당 인덱스를 읽는 parallel대신 xargs스레드를 사용하는 것이 좋습니다 . 그래도이 질문의 범위를 벗어납니다. 나는 또한 똑바로 얼굴로 썼다. 왜 그렇게 많이 신경 쓰나요? 영화 및 오디오 파일을 찾고있을 수 있습니다. 또는 특정 유형의 사진; 또는 프로젝트 데이터 디렉토리의 이진 실행 파일.


1
asker의 이름이으로 끝나지 않는 PDF 파일이있는 상황과 동일 하다면 , .pdf귀하의 의견을 높이 평가할 것입니다. 그러나 그것은 비교적 드문 상황입니다 (직종에도 불구하고) 우리는 그 asker가 실제로 그것을 처리해야한다고 믿을 이유가 없습니다. 따라서 당신이 만들고있는 요점이 유효하지만 산만하다고 생각합니다- 그리고 당신이 말한 강력한 방법은 "(아마도) 유용하지 않은"영역으로 답을 밀어 넣습니다. (물론 내 의견 만.)
David Z

우리는 현혹 적이기 때문에 PoC || GTFO 폴리 글 로트 와 같은 PDF를 어떻게 처리 할 것 입니까?
Stephen Kitt

@StephenKitt-당신이 묻는 것이 확실하지 않지만 나는 흥미 롭습니다. 펑키 한 이름이없는 일반 PDF처럼 보입니다. 이것들이 내 제안 된 해결책에 실패합니까?
Rich

@DavidZ 나는 그것에 대해 무엇을 말할지 잘 모르겠습니다. 내 말은, 내가 이미 많은 말을했을 때 내가 멍청하다는 것을 지적하는 것이 약간의 관용적이지 않습니까? "유용하지 않은"이유는 다음과 같습니다. PDF를 찾는 좋은 솔루션은 스크립트, 이진 실행 파일, 라이브러리, 미디어 파일 등 을 찾는 데 적합한 솔루션 이어야합니다 . "압축 된 Mach 실행 파일"에 대한 다른 답변이지만 배우고 자합니다.
Rich

1
@Rich 많은 PDF는 ZIP 파일이며, 일부는 이미지 또는 부팅 가능한 가상 머신입니다. 힌트에 대해서는 처음 몇 가지 문제에 대한 "스포일러"링크를 참조하십시오. 나머지는 PDF 자체에 문서화되어 있습니다.
스티븐 키트
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.