Shell Script - Obter todos os arquivos modificados após <data>

136

Prefiro não fazer isso em PHP, por isso espero que alguém decente em scripts de shell possa ajudar.

Eu preciso de um script que percorra o diretório recursivamente e encontre todos os arquivos com a data da última modificação superior a alguma data. Em seguida, ele tarará e compactará o (s) arquivo (s) mantendo as informações do caminho.

Jonathan Leffler
fonte
14
Boa decisão para não fazê-lo em PHP.
Kredns
1
Você pode usar qualquer uma das linguagens de script de shell decentes, por exemplo, python, ruby, perl sem recorrer ao php.
Garrow
3
@garrow Isso seria bastante simples no PHP usando um RecursiveDirctoryIterator encapsulado em um FilterIterator.
Artefacto

Respostas:

136

tão simples quanto:

find . -mtime -1 | xargs tar --no-recursion -czf myfile.tgz

onde find . -mtime -1selecionará todos os arquivos no diretório atual (recursivamente) modificado no dia anterior. você pode usar frações, por exemplo:

find . -mtime -1.5 | xargs tar --no-recursion -czf myfile.tgz
skrat
fonte
4
Veja a resposta do usuário104848 abaixo para saber como lidar com espaços em seus nomes de arquivo
Brian Henk
8
Converter um carimbo de data / hora arbitrário em uma quantidade relativa de tempo fracionária não parece correto nem particularmente conveniente. A solução abaixo -newermté muito melhor.
Bobby Jack
5
Ao tentar extrair qualquer arquivo com alterações em uma estrutura com diretórios, os próprios diretórios são marcados como modificados, causando o arquivamento de toda a pasta. Adicione -type fapenas aos arquivos selecionados. Isso mantém a estrutura da pasta, mas faz backup apenas dos arquivos com alterações.
Brent
1
@BrianHenk user104848 mudou seu nome, eu tenho certeza que você quer dizer esta resposta a partir de (atualmente) Jason Luther embora
icc97
4
A pergunta pede para encontrar arquivos até uma data arbitrária. Esta resposta é como encontrar arquivos por um número arbitrário de dias no passado. Não acho que essa seja a resposta aceita sem adicionar uma etapa para converter uma data em um delta de dia.
Mark
91

Se você possui o GNU find, há uma legião de opções relevantes. O único problema é que a interface para eles é menos do que estelar:

  • -mmin n (tempo de modificação em minutos)
  • -mtime n (hora da modificação em dias)
  • -newer file (hora da modificação mais recente que a hora do arquivo)
  • -daystart (ajuste a hora de início da hora atual para o início do dia)
  • Mais alternativas para o tempo de acesso e o tempo de 'alteração' ou 'criação'.

A parte difícil é determinar o número de minutos desde então.

Uma opção que vale a pena considerar: use touchpara criar um arquivo com o carimbo de data / hora de modificação necessário; então use findcom -newer.

touch -t 200901031231.43 /tmp/wotsit
find . -newer /tmp/wotsit -print
rm -f /tmp/wotsit

Ele procura por arquivos mais recentes que 2009-01-03T12: 31: 43. Claramente, em um script, /tmp/wotsithaveria um nome com o PID ou outro valor para torná-lo único; e haveria um trappara garantir que ele seja removido, mesmo que o usuário interrompa, e assim por diante.

Jonathan Leffler
fonte
65
Em vez disso, você pode usar -newermt '2009-01-03T12:31:43'para evitar a necessidade de criar um arquivo apenas para referência.
Michael Mior
@MichaelMior: Interessante - o 'find' no MacOS X 10.7.2 suporta -newermt(documentado em -newerXYuma vez que existem várias opções; neste caso, X = m, Y = t). A localização do GNU nos sistemas Linux (quase arcaicos) que eu uso não suporta as opções, portanto é uma chegada relativamente recente. Obrigado pela atenção.
precisa saber é o seguinte
Esta opção está presente no GNU find 4.4.2 que estou usando no meu sistema.
Michael Mior
2
Observe também que o GNU find também suporta tempos relativos, ie. -newermt '-2 weeks'.
Cybolic
1
-newermt '2009-01-03T12:31:43'parece incrível, mas infelizmente parece interpretar tudo no fuso horário errado: lists.gnu.org/archive/html/bug-findutils/2012-12/msg00009.html
Antoine
35

Você pode fazer isso diretamente com tar e ainda melhor:

tar -N '2014-02-01 18:00:00' -jcvf archive.tar.bz2 files

Isso instrui o tar a compactar arquivos mais recentes que 1º de janeiro de 2014, 18:00:00.

linux_newbie
fonte
9
Hein ... eu uso o Unix desde 1984 e nunca soube disso. Sempre algo para aprender.
John John
As implementações tarfornecidas com o OS X e o FreeBSD suportam apenas o --newerque é a opção longa -Nno GNU tar.
nisetama
Isso é incrível ... Eu só consegui fazê-lo funcionar com bzip, sem usar -xcvf e uma extensão gz ... mas não sou especialista.
Phil
17

Isso funcionará para algum número de arquivos. Você deseja incluir "-print0" e "xargs -0" caso algum dos caminhos possua espaços. Este exemplo procura por arquivos modificados nos últimos 7 dias. Para encontrar aqueles modificados antes dos últimos 7 dias, use "+7".

find . -mtime -7 -print0 | xargs -0 tar -cjf /foo/archive.tar.bz2

Como esta página avisa, o xargs pode fazer com que o comando tar seja executado várias vezes se houver muitos argumentos, e o sinalizador "-c" pode causar problemas. Nesse caso, você deseja o seguinte:

find . -mtime -7 -print0 | xargs -0 tar -rf /foo/archive.tar

Você não pode atualizar um arquivo tar compactado com tar, portanto, é necessário bzip2 ou gzip em uma segunda etapa.

Jason Luther
fonte
1
Em relação ao segundo ponto, você pode usar um comando tar habilitado para gzip, como a opção -z do Gnu tar, para atualizar arquivos compactados também.
Suncat2000
Ou adicione a opção 'j' para usar o bzip nos tars GNU recentes
hd1 22/02
3
Como eu disse acima na resposta de Jonathan, isso irá capturar as pastas com alterações, causando a importação de todos os seus arquivos. Adicione -type fapenas aos arquivos selecionados. Isso mantém a estrutura da pasta, mas apenas faz backup dos arquivos com alterações / adicionadas recentemente.
Brent
12

Isso deve mostrar todos os arquivos modificados nos últimos 7 dias.

find . -type f -mtime -7 -print

Coloque isso no tar / zip, e você deve ser bom.

Chris Doggett
fonte
3

bem no linux tente ler a página de manual do comando find

man find

algo assim deveria

 find . -type f -mtime -7 -print -exec cat {} \; | tar cf - | gzip -9

e você tem

Luixv
fonte
3

Você pode obter uma lista dos arquivos modificados pela última vez depois de x dias atrás com:

find . -mtime -x

Então você só precisa tar e compactar arquivos na lista resultante, por exemplo:

tar czvf mytarfile.tgz `find . -mtime -30`

para todos os arquivos modificados durante o mês passado.

mouviciel
fonte
3
"-mtime x" corresponde aos arquivos modificados exatamente "x" dias atrás, use "-mtime -x" para corresponder aos arquivos modificados há menos de "x" dias atrás.
Lance Richardson
3

Eu simplesmente faria o seguinte para fazer backup de todos os novos arquivos de 7 dias atrás

tar --newer $(date -d'7 days ago' +"%d-%b") -zcf thisweek.tgz .

observe que você também pode substituir '7 dias atrás' por qualquer coisa que atenda às suas necessidades

Pode ser : date -d'yesterday' +"%d-%b"

Ou até: date -d'first Sunday last month' +"%d-%b"

Michel
fonte
2

Este script encontrará arquivos com uma data de modificação de dois minutos antes e depois da data especificada (e você pode alterar os valores nas condições conforme sua exigência)

PATH_SRC="/home/celvas/Documents/Imp_Task/"
PATH_DST="/home/celvas/Downloads/zeeshan/"

cd $PATH_SRC
TODAY=$(date  -d "$(date +%F)" +%s)
TODAY_TIME=$(date -d "$(date +%T)" +%s)


for f in `ls`;
do
#       echo "File -> $f"
        MOD_DATE=$(stat -c %y "$f")
        MOD_DATE=${MOD_DATE% *}
#       echo MOD_DATE: $MOD_DATE
        MOD_DATE1=$(date -d "$MOD_DATE" +%s)
#       echo MOD_DATE: $MOD_DATE

DIFF_IN_DATE=$[ $MOD_DATE1 - $TODAY ]
DIFF_IN_DATE1=$[ $MOD_DATE1 - $TODAY_TIME ]
#echo DIFF: $DIFF_IN_DATE
#echo DIFF1: $DIFF_IN_DATE1
if [[ ($DIFF_IN_DATE -ge -120) && ($DIFF_IN_DATE1 -le 120) && (DIFF_IN_DATE1 -ge -120) ]]
then
echo File lies in Next Hour = $f
echo MOD_DATE: $MOD_DATE

#mv $PATH_SRC/$f  $PATH_DST/$f
fi
done

Por exemplo, você deseja que os arquivos tenham data de modificação apenas antes da data especificada, você pode alterar 120para 0no $DIFF_IN_DATEparâmetro descartando as condições do $DIFF_IN_DATE1parâmetro.

Da mesma forma, se você deseja que os arquivos tenham data de modificação 1 hora antes e depois da data especificada, substitua 120por 3600in if CONDITION.

Zeeshan Ali
fonte