Como sei que são PDFs?
Você não a menos que você pergunte. Claro, estou sendo pedante, mas você não perguntou sobre arquivos com .pdf
em seus nomes . Só porque um arquivo tem os caracteres .pdf
no nome do arquivo não faz dele um arquivo PDF .
Na verdade, vamos ser todo o caminho pedante sobre isso: se os últimos quatro caracteres do nome de um arquivo forem .pdf
, então ele sempre terá mais de três caracteres em seu nome .
Então, fazendo isso do jeito errado , você pode dizer:
$ find . -type f -name "*???.pdf"
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Setup_MagicISO.exe.pdf
Veja esse segundo? Na verdade, é um executável. (Eu sei, eu mudei o nome.) E eu também estou sentindo falta de um PDF que eu poderia jurar estava no diretório Documentos ...
$ ls Documents
McLaren 720s Coupe:Order Summary.pdf
Pioneer Premier DEH-P490IB CD Install Manual.PDF
Setup_MagicISO.exe.pdf
Então, usando -iname
, poderíamos encontrar esse, mas ainda está criando esse arquivo não-PDF.
O que nós realmente queremos fazer neste caso é examinar o número mágico do arquivo usando o comando file
. Uma opção gera o tipo MIME , que é mais simples de analisar. A consulta find
se torna um simples -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
Vamos usar o delimitador de dois pontos e procurar o tipo MIME application/pdf
, depois zerar essa parte e imprimir o resultado. Tome nota, um dos meus arquivos tem dois pontos no nome; então eu não posso simplesmente pedir ao awk para ($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
Agora vamos terminar inventando arquivos PDF com o nome a
e 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
Isso é tudo. Eu sei que provavelmente vou ser dinged por ser horrivelmente pedante, mas no meu trabalho com milhares de volumes NFS para caçar e todos os tipos de arquivos com nomes ruins, eu desejo que mais pessoas sejam pedantes.
Editado para adicionar: no mundo real, talvez eu queira usar updatedb
para criar um índice de arquivo pesquisável, locate
em vez de find
ler esse índice e parallel
em vez de xargs
para encadear. Isso está um pouco fora do escopo desta questão. Eu escrevi isso com uma cara séria também. Por que eu me importo tanto? Eu poderia estar procurando por arquivos de filme e áudio; ou certos tipos de fotografias; ou executáveis binários em um diretório de dados do projeto.