Respostas:
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
.pdf
in filenamePor exemplo, se houver um diretório chamado temp
na sua pasta pessoal:
cd ~/temp
exclua os arquivos:
find . -type f ! -iname "*.pdf" -delete
Isso excluirá todos os arquivos, exceto xyz.pdf
.
Você pode combinar esses dois comandos para:
find ~/temp -type f ! -iname "*.pdf" -delete
.
é o diretório atual. !
significa levar todos os arquivos, exceto os que estão .pdf
no final. -type f
seleciona apenas arquivos, não diretórios. -delete
significa excluí-lo.
!
deve vir antes -name
. simplesmente -name
vai incluir apenas .pdf
, enquanto que -iname
irá incluir tanto .pdf
e.PDF
Para excluir apenas no diretório atual e não nos subdiretórios, adicione -maxdepth 1
:
find . -maxdepth 1 -type f ! -iname "*.pdf" -delete
.
significa diretório atual. !
significa levar todos os arquivos, exceto aquele com .pdf
no final. -delete
significa excluí-lo. estou claro agora?
-maxdepth 1
parâmetro para começar. Em seguida, sugira a remoção do parâmetro, caso se queira excluir recursivamente.
Com bash
o globbing estendido do shell, você pode remover qualquer arquivo com extensões que não sejam o .pdf
uso de
rm -- *.!(pdf)
Conforme observado por @pts, os --
caracteres indicam o final de qualquer opção de comando, tornando o comando seguro no caso raro de arquivos cujos nomes começam com um -
caractere.
Se você deseja excluir arquivos sem qualquer extensão, bem como aqueles com extensões diferentes .pdf
, como indicado por @DennisWilliamson, você pode usar
rm -- !(*.pdf)
O globbing estendido deve ser ativado por padrão, mas se não, você pode fazê-lo usando
shopt -s extglob
Especialmente se você pretende usar isso dentro de um script, é importante observar que, se a expressão não corresponder a nada (por exemplo, se não houver arquivos que não sejam pdf no diretório), por padrão, o globo será passado sem expansão para o diretório rm
comando, resultando em um erro como
rm: cannot remove `*.!(pdf)': No such file or directory
Você pode modificar esse comportamento padrão usando a nullglob
opção shell, no entanto, isso tem seu próprio problema. Para uma discussão mais aprofundada, consulte NullGlob - Greg's Wiki
rm *~*.pdf
!(*.py)
. Além disso, presumivelmente, se o OP desejar apenas arquivos ".pdf" restantes, os arquivos sem extensões também deverão ser excluídos e não ignorados.
$ cd <the directory you want>
$ gvfs-trash !(*.pdf)
Ou via mv
comando (mas dessa maneira você não pode restaurá-lo a partir do Lixo, pois ele não registra informações de .trashinfo, isso significa que você moveu seus arquivos para um destino onde estão os seguintes).
mv !(*.pdf) ~/.local/share/Trash/files
rm
.
A abordagem mais fácil: crie outro diretório em algum lugar (se você estiver excluindo apenas um diretório, não recursivamente, pode até ser um subdiretório); mova todos os .pdf para lá; exclua todo o resto; mover as costas do pdf; exclua o diretório intermediário.
Rápido, fácil, você pode ver exatamente o que está fazendo. Apenas verifique se o diretório intermediário está no mesmo dispositivo que o diretório que você está limpando, para que as mudanças sejam renomeadas, não cópias!
Use o GLOBIGNORE do bash:
GLOBIGNORE=x.pdf:a.pdf
rm *
unset GLOBIGNORE
Na página de manual do bash:
GLOBIGNORE: Uma lista de padrões separados por dois pontos que define o conjunto de nomes de arquivos a serem ignorados pela expansão do nome do caminho.
Um teste rápido:
mkdir /tmp/foooooo
cd /tmp/foooooo
touch x.pdf y.zip z.mp3 a.pdf
GLOBIGNORE=x.pdf:a.pdf
ls -1 *
Resultado:
y.zip z.mp3
Aqui está uma abordagem que eu gosto, porque me permite ter muito cuidado: componha uma maneira de mostrar apenas os arquivos que quero excluir e envie-os para o rm
uso xargs
. Por exemplo:
ls
me mostra tudols | grep pdf
mostra os arquivos que eu quero manter. Hmm.ls | grep -v pdf
mostra o oposto: tudo, exceto o que eu quero manter. Em outras palavras, mostra a lista de itens que quero excluir. Posso confirmar isso antes de fazer qualquer coisa perigosa.ls | grep -v pdf | xargs rm
envia exatamente essa lista rm
para exclusãoComo eu disse, gosto principalmente dessa segurança: não é acidental rm *
para mim. Duas outras vantagens:
ls
ou find
para obter a lista inicial, como preferir. Você pode usar qualquer outra coisa que desejar no processo de restringir essa lista - outra grep
, alguma awk
ou qualquer outra coisa. Se você precisar excluir apenas arquivos cujos nomes contenham uma cor, você poderá criar da mesma maneira.find
para encontrar e rm
remover, em vez de ter que lembrar que find
aceita uma -delete
bandeira. E se você fizer isso, novamente, poderá compor soluções alternativas; talvez em vez de rm
, você possa criar um trash
comando que mova o arquivo para a lixeira (permitindo "undeletion") e canalize para ele em vez de rm
. Você não precisa ter find
suporte para essa opção, apenas a utiliza.Veja os comentários de @pabouk para saber como modificar isso para lidar com alguns casos extremos, como quebras de linha em nomes de arquivos, nomes de arquivos como my_pdfs.zip
etc.
pdf
qualquer lugar em seu nome. --- b) Exclui arquivos PDF se alguma letra do sufixo estiver em maiúsculas. --- c) Não é uma boa ideia usar a saída de ls
. Não funcionará com nomes de arquivos contendo novas linhas. Algumas implementações de ls
substituir caracteres especiais, por exemplo, tabular por ?
. --- É melhor utilização: find -maxdepth 1 -print0
. (não tão curto quanto ls
:) ----- Para resolver a) eb) use grep -vi '\.pdf$'
--- solução completa (mas apenas GNU):find -maxdepth 1 -print0 | grep -viz '\.pdf$' | xargs -0 rm
| head -20
pelo menos ver se parece mais ou menos correto, enquanto se você apenas rm my_pattern
não tiver chance de detectar um grande erro.
find . -type f ! -name "*.pdf"
para imprimir no console ou canalizar para menos ou um arquivo. [e depois tubo para xargs para rm se desejado como comentários de pabouk (com a -print0 | ... -0 para nomes de arquivos estranhos)]
Normalmente, resolvo esses problemas com o interpretador interativo Python:
mic@mic ~ $ python
>>> import os
>>> for f in os.listdir('.'):
... if not f.endswith('.pdf'):
... os.remove(f)
Pode ser mais longo que um one-liner com find
or xargs
, mas é extremamente resistente, e eu sei exatamente o que ele faz, sem precisar pesquisar primeiro.
for item in [f for f in os.listdir('.') if not f.endswith('.pdf')]: os.remove(item)
python -c "import os; for f in os.listdir('.'): if not f.endswith('.pdf'): os.remove(f)"
[os.remove(f) for f in os.listdir('.') if not f.endswith('.pdf')]
melhor resposta (em comparação com a minha resposta anterior) a esta pergunta será usando o file
comando poderoso .
$ file -i abc.pdf
abc: application/pdf; charset=binary
agora seu problema:
cd <the directory you want to search in>
for var in ./*
do
if file -i "$var" | grep -q 'application/pdf\;'
then
echo "$var"
fi
done
o trabalho de for
comando é dar os arquivos no diretório atual na forma de variável $var
. if-then
O comando gera os nomes dos arquivos pdf assumindo o status de saída de 0
from file -i "$var" | grep -q 'application/pdf\;'
, ele fornecerá o status de saída 0
somente se encontrar arquivos PDF.
rm $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
Aviso! Melhor tentar primeiro
ls -l $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
-i
com grep
para a correspondência de maiúsculas e minúsculas.
rm -i -- !(*@(a|x).pdf)
Leia como, remova todos os arquivos que não são a.pdf
ou x.pdf
.
Isso funciona, fazendo uso de 2 globs estendidos, o exterior !()
para negar o glob contido que se exige que o glob deve corresponder a um ou mais a
ou x
padrões antes do .pdf
sufixo. Veja glob # extglob .
$ ls -a
.dotfile1 .dotfile2 a.pdf x.pdf y.zip z.mp3
$ echo -- !(a.pdf)
-- x.pdf y.zip z.mp3
$ echo -- !(x.pdf)
-- a.pdf y.zip z.mp3
$ echo -- !(a.pdf|x.pdf)
-- y.zip z.mp3
$ echo -- !(@(a|x).pdf) # NOTE.that this matches the .dotfiles* as well
-- . .. .dotfile1 .dotfile2 y.zip z.mp3
$ echo -- !(*@(a|x).pdf) # but this doesn't
-- y.zip z.mp3
$ echo rm -i -- !(*@(a|x).pdf)
rm -i -- y.zip z.mp3
$ ksh -c 'for i in ./*; do case $i in *.pdf)continue;; *)rm "$i";; esac;done'
Praticamente POSIX e compatível com qualquer shell Bourne-style ( ksh
, bash
, dash
). Adequado para scripts portáteis e quando você não pode usar bash
o globbing de shell estendido.
$ perl -le 'opendir(my $d,"."); foreach my $f (grep(-f && !/.pdf/ , readdir($d))){unlink $f};closedir $d'
Ou um pouco mais limpo:
$ perl -le 'opendir(my $d,"."); map{ unlink $_ } grep(-f "./$_" && !/.pdf/ , readdir($d));closedir $d'
python -c 'import os;map(lambda x: os.remove(x), filter(lambda x: not x.endswith(".pdf"),os.listdir(".")))'
Cuidado com o que você está excluindo!
Uma maneira segura de testá-lo antes de tentar excluir é testá-lo primeiro ls
, pois alguns comportamentos não capturados podem excluir arquivos indesejados. E você pode fazer isso diretamente fora do diretório. ls
é semelhante a rm
, então:
ls sub/path/to/files/!(*.pdf)
Isto irá listar
y.zip
z.mp3
E agora você pode ver o que está excluindo e pode excluí-los com segurança:
rm sub/path/to/files/!(*.pdf)
E é isso. Você pode usar curinga *
para ser mais seletivo, como manter apenas os documentos do curso de programação:
rm sub/path/to/files/!(*programming*)
.
significa "e"?!
significa "exceto"-name
significa que você deseja excluir por um parâmetro de nome e, em seguida,-delete
a ação a ser tomada ao encontrar? Então, ele procura por tudo, exceto "* .pdf", e os exclui? Ou eu entendi mal?