Você pode usar este script:
#!/bin/bash
for i in $(find Your_Mail_Dir/ -newermt "2011-01-01" ! -newermt "2011-12-31"); do
mv $i /moved_emails_dir/
done
Eu tenho uma conta de e-mail que recebeu mais de 60 GB de e-mails, e atualmente estou tendo muitos problemas para usar um cliente de e-mail para arquivar e-mails do ano passado (2011).
Via terminal, estou tentando usar localizar para localizar os arquivos entre 2011 -01-01 e 2011-12-31, mas sem sucesso.
Como posso encontrar arquivos entre duas datas?
Se for relevante, o objetivo final será um lote que moverá cada arquivo encontrado, correspondente ao intervalo de datas, para uma pasta.
Você pode usar este script:
#!/bin/bash
for i in $(find Your_Mail_Dir/ -newermt "2011-01-01" ! -newermt "2011-12-31"); do
mv $i /moved_emails_dir/
done
Bash encontra arquivos entre duas datas:
find . -type f -newermt 2010-10-07 ! -newermt 2014-10-08
Retorna uma lista de arquivos com registros de data e hora depois de 2010-10-07 e antes de 2014-10-08
Bash encontra arquivos de 15 minutos atrás até agora:
find . -type f -mmin -15
Retorna uma lista de arquivos com registros de data e hora depois de 15 minutos atrás, mas antes.
Bash encontra arquivos entre dois timestamps:
find . -type f -newermt "2014-10-08 10:17:00" ! -newermt "2014-10-08 10:53:00"
Retorna arquivos com registros de data e hora entre 2014-10-08 10:17:00
e 2014-10-08 10:53:00
Como Subv3rsion e As respostas de Eric Leschinski mostram que o predicado -newermt
seleciona os arquivos modificados mais recentemente do que a data (e a hora opcional) especificada como seu operando. Para encontrar arquivos
srcdir
(ou seja, incluindo seus subdiretórios, seus subdiretórios, etc.) destdir
... você pode executar:
find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -i {} destdir/ \;
Em uma expressão -exec
, find passa o nome do arquivo encontrado no lugar de {}
. ;
significa para -exec
que o comando a ser executado e seus argumentos foram todos fornecidos (no caso de expressões subseqüentes serem passadas para localizar após os argumentos específicos do predicado -exec
- veja abaixo um exemplo disso) . ;
deve ser escapado como \;
, por isso não é interpretado especialmente pelo shell. (Sem \
, ;
terminaria todo o comando find
, funcionando da mesma forma que uma nova linha. Mesmo que esse comando find
não tenha nada após essa expressão -exec
, a falha em transmitir o argumento ;
é ainda um erro de sintaxe.)
Se você quiser apenas listar os arquivos - o que é recomendável se você não tiver certeza de como os e-mails antigos estão armazenados ou quais outros arquivos podem estar presentes - omite -exec
e tudo à direita. (Para e-mails, muitas vezes os e-mails de datas diferentes são armazenados no mesmo arquivo ; para alguém na situação descrita na pergunta aqui, recomendo investigar como eles são armazenados antes de mover qualquer arquivo.) Se você quiser para imprimir seus nomes e movê-los, adicione -print
antes de -exec
.
mv -i
solicita a qualquer momento que um arquivo seja sobrescrito no destino, como acontece se:
srcdir
, já foi movido durante a mesma operação find
, ou
srcdir
durante a mesma operação find
, depois que o original foi movido, mas logo será encontrado uma vez find
atravessa um subdiretório diferente. rm
: Você tem outras opções para lidar com arquivos com nomes duplicados.
-i
(ou seja, mv {} destdir/
), mv
normalmente não solicitaria aprovação, mas o faria se o arquivo de destino fosse somente leitura. ( mv
pode até ser bem-sucedido ao sobrescrever um arquivo somente leitura algumas vezes, como, por exemplo, se o usuário que o executa possuir o arquivo.) mv
sempre (tente) sobrescreva arquivos com nomes idênticos, use mv -f
. mv -n
. mv
aceita os sinalizadores -b
e --backup
para renomear automaticamente os arquivos com nome idêntico que já existem no destino. Por padrão, ~
é adicionado para produzir o nome do backup e, se um arquivo com o nome e um arquivo com o nome de backup já existir no destino, o arquivo de backup será sobrescrito. Esse padrão pode ser substituído pelas opções transmitidas ao chamar mv
e pelas variáveis de ambiente. Consulte man mv
para obter detalhes e o exemplo abaixo. Para mover todos os arquivos, fazer backup de arquivos com nomes duplicados usando um sufixo ~
e usar sufixos .~n~
numerados quando arquivos .~
já existirem (para evitar sobrescrever qualquer coisa), execute:
find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv --backup=existing {} destdir/ \;
Se você usa mv -n
e deseja saber quais arquivos não foram movidos porque havia outro arquivo com o mesmo nome, provavelmente a melhor maneira é executar o comando find
original novamente, sem -exec
e tudo à direita dele. Isso imprimirá seus nomes.
Ele também imprimirá os nomes de todos os arquivos correspondentes criados desde que você executou o comando find .... -exec ...
original, mas para esse aplicativo normalmente não haverá nenhum, pois você está procurando arquivos com tempos de modificação antigos. É possível fornecer a um arquivo um registro de data e hora de modificação mais antigo do que a sua idade real, com touch
e outros mecanismos, mas isso não parece provável de ocorrer neste caso sem o seu conhecimento.
mv -n
não informa, nem retorna nenhum código de saída especial, quando se abstém de mover um arquivo.Portanto, se você deseja ser imediatamente informado sobre os arquivos ignorados enquanto find
é executado, será necessário fazer uma etapa separada para isso. Uma maneira é:
find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -n {} destdir/ \; \
-exec [ -f {} ] \; -exec printf "\'%s' skipped (exists in \'%s')\n" {} destdir \;
Algumas considerações técnicas menores: Isso avisa incorretamente se mv
não copia um arquivo por um motivo diferente do existente no destino e sai reportando sucesso . Isso parece improvável, mas não tenho certeza se é impossível. Ele também sofre potencialmente uma condição de corrida : ele avisa quando não há nenhum erro real, se um novo arquivo do mesmo nome foram criados no mesmo local durante o curto espaço de tempo após o arquivo antigo ser movido e antes da verificação para ver se ele foi removido. (Considerando o aplicativo, duvido que algum problema realmente ocorra). Ele poderia ser reescrito para verificar o destino antes mover o arquivo em vez de depois: então a condição de corrida estaria relacionada aos arquivos de destino recém-criados de arquivos de origem. E, embora os erros e avisos relatados por find
ou mv
(ou [
, embora não haja nenhum), serão gravados em erro padrão , nosso aviso ...skipped (exists in...
é gravado em padrão saída . Normalmente, ambos aparecem no seu terminal, mas isso pode ser importante se você estiver criando scripts.
Eu dividi o comando em duas linhas para facilitar a leitura. Pode ser executado dessa forma ou você pode remover o \
e a nova linha (ou seja, a quebra de linha).
find
? find
predicados podem ser testes (como -type
e -newermt
), usados para seus valores de retorno, ou ações (como -print
e -exec
), que são frequentemente usados para seus efeitos colaterais.
Quando nenhum operador (como -a
para e -o para ou ) é fornecido entre expressões, -a
está implícito. find
emprega avaliação de curto-circuito para e e ou . p q
(ou seja, p -a q
) é verdadeiro somente se as expressões p e q forem verdadeiras, então q não precisa ser avaliado se p é falso. Embora muitas vezes não pensemos nisso nesses termos, é por isso que os testes devem ser verdadeiros para as ações ou testes subsequentes a serem avaliados. Por exemplo, suponha que find
apareça em um diretório. Ele avalia -type f
para false, então ele pode pular tudo depois.
Como testes, as ações são avaliadas como verdadeiras ou falsas também. Dessa forma, -exec
informa se o comando executado foi encerrado relatando sucesso (verdadeiro) ou falha (falso). Temos essa cadeia de -exec
expressões conectadas com implícito e :
-exec mv -n {} destdir/ \; -exec [ -f {} ] \; -exec printf "\'%s' skipped (exists in \'%s')\n" {} destdir \;
Isso tenta mover o arquivo e, se mv
reportar falha, parar. Não queremos avisar sobre um arquivo ignorado corretamente se algum outro problema for o motivo pelo qual ele não foi movido.
Mas, se tiver êxito, ele executa o comando [
. Como find
, [
suporta seu próprio tipo de expressões passadas como argumentos. [ -f {} ]
verifica se o operando após -f
(passado a ele por find
no lugar de {}
) existe (e é um arquivo regular) e retorna true / success ou false / failure. sub> (Os status de saída de muitos comandos são melhor interpretados como significando sucesso ou falha, mas o status de [
é geralmente melhor interpretado como verdadeiro ou falso.)
Se [
retornou false, o arquivo desapareceu, por isso foi movido, portanto não há necessidade de fazer nada. Mas se [
retornou false, o arquivo ainda está lá. Então find
avalia a próxima expressão -exec
, que imprime a mensagem de aviso.
man find
e o Manual de referência do GNU Findutils
man mv
e o Manual de referência do GNU Coreutils (especialmente 11.4 mv
: Mover arquivos (renomear) ) man \[
e 16.3 test: Verifique os tipos de arquivo e compare os valores nos documentos do Coreutils /usr/bin/[
), e não o [
builtin do shell é o find
que é executado quando você usa -exec [
.
Tags command-line find