Temukan semua PDF dengan setidaknya tiga karakter dalam namanya

9

Saya ingin mencari file PDF yang namanya (tidak termasuk ekstensi) lebih besar dari tiga.

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

mengembalikan apa-apa, tetapi

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

bekerja.

Bagaimana saya bisa mengaktifkan {3,}varian?

Kalkulus
sumber
Berapa panjang? Panjang nama file? Panjang halaman?
Ignacio Vazquez-Abrams

Jawaban:

18

Dengan anggapan Anda menggunakan GNU find(yang kemungkinan besar adalah Anda, karena -iregexmerupakan ekstensi GNU ke POSIXfind ), -regexdan -iregexdefault untuk ekspresi reguler Emacs, yang tidak dikenali {3,}. Anda perlu menentukan jenis ekspresi reguler yang berbeda menggunakan -regextypeopsi; selain itu, Anda perlu menyesuaikan ekspresi reguler Anda dengan fakta bahwa ekspresi cocok dengan path lengkap:

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

Anda juga harus melarikan diri .sehingga cocok dengan “.” daripada karakter apa pun:

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

Ekspresi reguler dapat disederhanakan karena kami hanya peduli pada tiga karakter non-“/”:

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

Untuk kelengkapan, dengan FreeBSD atau NetBSD find(implementasi lain yang mendukung -iregex, bukan milik Anda meskipun .+tidak akan bekerja di sana tanpanya -E), Anda akan menulis:

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

atau:

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

Tanpa -E, itulah ekspresi reguler dasar (seperti dalam grep) dan dengan -E ekspresi reguler yang diperluas (seperti dalam grep -E).

Dengan ast-open find:

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

(Itu diperpanjang regexps di luar kotak).

Stephen Kitt
sumber
20

Ini lebih mudah dengan wildcard standar:

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

Atau dengan beberapa findimplementasi (yang mendukung -regexjuga mendukung -iname):

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

Untuk jumlah karakter yang sewenang-wenang alih-alih 3, di situlah Anda dapat memilih untuk kembali ke -iregextempat yang tersedia (lihat jawaban @Stephen Kitt ) atau Anda dapat menggunakan zshatau ksh93menggila:

  • zsh:

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

    ( (D)untuk mempertimbangkan file tersembunyi dan file dalam dirs seperti suka dengan find)

    • (#cx,y)adalah zshekuivalen wildcard dari regexp{x,y}
    • (#i) untuk case sensitive
    • ?wildcard standar untuk setiap karakter tunggal (seperti regexp .)
    • **/: setiap tingkat subdirektori (termasuk 0)
  • ksh93:

    FIGNORE='@(.|..)' # to consider hidden files
    set -o globstar
    printf '%s\n' **/{3,}(?).~(i:pdf)
    
    • @(x|y): operator wildcard extended ksh mirip dengan regexp (x|y).
    • FIGNORE: variabel khusus yang mengontrol file apa yang diabaikan oleh gumpalan. Saat disetel, pengabaian file tersembunyi yang biasa tidak dilakukan, tetapi kami masih ingin mengabaikan entri direktori .dan ..jika ada.
    • {x,y}(z)adalah ksh93's setara dengan regexp z{x,y}.
    • ~(i:...): pencocokan case-insensitive.

Gumpalan memiliki beberapa keuntungan tambahan di findsini karena Anda mendapatkan daftar yang diurutkan (Anda dapat menonaktifkan penyortiran itu zshdengan oNkualifikasi glob, atau menggunakan kriteria penyortiran yang berbeda) dan juga berfungsi ketika nama file berisi urutan byte yang tidak membentuk karakter yang valid (untuk Misalnya, di lokal menggunakan charset UTF-8, findpendekatan tersebut akan gagal untuk melaporkan a $'St\xE9phane Chazelas - CV.pdfkarena \xE9karakter yang tidak cocok dengan regexp .atau wildcard ?atau *dengan GNU find).

Stéphane Chazelas
sumber
Apakah ini akan berhasil untuk Bash? shopt -s dotglob globstar; printf '%s\n' ~/**/*???.[pP][dD][fF]
wjandrea
7

Bagaimana saya tahu itu PDF?

Anda tidak melakukannya kecuali jika Anda bertanya. Tentu, saya menjadi orang yang sangat bertele-tele, tetapi Anda tidak bertanya tentang file dengan .pdfnama mereka . Hanya karena file memiliki karakter .pdfdalam nama file tidak menjadikannya file PDF .

Bahkan, mari kita menjadi serba bisa tentang ini: jika empat karakter terakhir dari nama file .pdf, maka akan selalu memiliki lebih dari tiga karakter dalam namanya .

Jadi melakukan ini dengan cara yang salah , Anda mungkin berkata:

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

Lihat yang kedua? Ini sebenarnya sebuah executable. (Saya tahu, saya mengganti namanya.) Dan saya juga kehilangan PDF yang saya sumpah ada di direktori Documents ...

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

Jadi dengan menggunakan -inamekita bisa menemukan yang itu, tapi itu masih mengaktifkan file bukan-PDF ini.

Apa yang benar - benar ingin kita lakukan dalam hal ini adalah memeriksa angka ajaib file menggunakan fileperintah. Satu opsi menampilkan tipe MIME , yang lebih mudah diurai. The findpermintaan kemudian menjadi sederhana -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

Mari kita gunakan pembatas titik dua, dan cari tipe MIME application/pdf, lalu nolkan bagian itu dan cetak hasilnya. Perhatikan, salah satu file saya memiliki titik dua di namanya; jadi saya tidak bisa hanya meminta 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

Sekarang mari kita selesaikan dengan contriving untuk menyertakan file PDF bernama adan 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

Itu saja. Saya tahu saya mungkin akan mendapatkan dahsyat karena menjadi pedantic yang mengerikan, tetapi dalam pekerjaan saya dengan ribuan volume NFS untuk diburu dan semua jenis file dengan nama buruk, saya berharap lebih banyak orang menjadi pedantic.

Diedit untuk menambahkan: di dunia nyata, saya mungkin ingin memanfaatkan updatedbuntuk membangun indeks file yang dapat dicari, locatealih-alih findmembaca indeks itu, dan parallelalih-alih xargsutas. Itu agak di luar ruang lingkup pertanyaan ini. Saya menulis itu dengan wajah lurus juga. Mengapa saya sangat peduli? Saya mungkin mencari file film dan audio; atau jenis foto tertentu; atau binary executable dalam direktori data proyek.

Kaya
sumber
1
Jika penanya memiliki situasi yang sama dengan yang Anda lakukan, di mana ada file PDF yang namanya tidak berakhir .pdf, maka keriaan Anda akan sangat dihargai. Tapi ini adalah situasi yang relatif tidak biasa (meskipun pekerjaan Anda) dan kami tidak memiliki alasan untuk percaya bahwa penanya sebenarnya harus menghadapinya, jadi saya pikir poin yang Anda buat, meskipun valid, agak mengganggu - dan saya pikir cara kuat Anda telah mengungkapkannya mendorong jawaban ke ranah "(mungkin) tidak berguna". (Pendapat saya saja, tentu saja.)
David Z
Karena kita bertele-tele, bagaimana Anda menangani PDF seperti Pogl | GTFO polyglots?
Stephen Kitt
@StephenKitt - Tidak yakin dengan apa yang Anda minta, tetapi saya tertarik. Mereka terlihat seperti PDF biasa bagi saya dengan nama yang tidak terlalu funky. Apakah ini gagal solusi yang saya sarankan?
Kaya
@ DavidZ Saya tidak yakin harus berkata apa untuk itu. Maksud saya, bukankah agak terlalu bagus untuk menunjukkan bahwa saya menjadi sangat hebat ketika saya sudah banyak bicara? Inilah mengapa itu tidak "tidak berguna": solusi yang baik untuk menemukan PDF harus menjadi solusi yang dapat disesuaikan untuk menemukan skrip, file biner yang dapat dieksekusi, perpustakaan, file media, dll. Saya bahkan tidak dapat mulai melihat bagaimana saya mengadaptasi salah satu jawaban lain untuk "executable Mach yang dikompresi", tapi saya bersedia belajar.
Kaya
1
@Kaya banyak PDF juga berupa file ZIP, beberapa juga gambar, atau bahkan mesin virtual yang dapat di-boot ... (Lihat tautan "spoiler" pada beberapa masalah pertama sebagai petunjuk; sisanya didokumentasikan dalam PDF sendiri.)
Stephen Kitt