Como posso listar recursivamente todos os arquivos que foram alterados entre 22.12.2011 e 24.12.2011?
Como posso listar recursivamente todos os arquivos que foram alterados entre 22.12.2011 e 24.12.2011?
Respostas:
De um modo geral, quando você estiver procurando arquivos em um diretório e seus subdiretórios recursivamente, use find
.
A maneira mais fácil de especificar um intervalo de datas find
é criar arquivos nos limites do intervalo e usar o -newer
predicado.
touch -t 201112220000 start
touch -t 201112240000 stop
find . -newer start \! -newer stop
-newer
é necessário aqui?
-newer
não é negado, o segundo é. "Encontre arquivos que são mais recentes que, start
mas não novos, que stop
".
start
e stop
.
Usando a solução de Gilles e depois de ler o homem, encontre (1) novamente, encontrei uma solução mais simples. A melhor opção é o -newerXY. Os sinalizadores m e t podem ser usados.
m The modification time of the file reference
t reference is interpreted directly as a time
Então a solução é
find . -type f -newermt 20111222 \! -newermt 20111225
O limite inferior em inclusivo e o limite superior são exclusivos, então eu adicionei 1 dia a ele! E é recursivo. Funciona bem no find v4.5.9.
find -newermt 20150212 \! -newermt 20150213 | xargs grep 'keyword' -m 50 -l
( -m 50
= pesquisa nas primeiras 50 linhas).
-exec ... +
em find(1)
, como: find -newermt 20150212 \! -newermt 20150213 -exec grep keyword -m 50 -l {} +
. Isso faz o mesmo, mas mais barato.
find 4.7.0-git
).
Supondo que você não precise de precisão em segundos, isso deve funcionar.
find . -type f -mmin -$(((`date +%s`-`date -d 20111222 +"%s"`)/60)) \! -mmin +$(((`date +%s`-`date -d 20111224 +"%s"`)/60))
EDIT: Alterado cmin
para mmin
após o comentário de @ Eelvex.
EDIT: '\!' ausência de
-cmin
é "alteração de status", -mmin
é "alteração de dados". Você provavelmente quer-mmin
find
pode levar um datetime no formato ISO; portanto, para um servidor no UTC, por exemplo, você pode especificar um deslocamento de várias horas a partir de onde estiver. Isso também garante a adição de um dia, pois você também está comparando o tempo:
find -type f -newermt 20111224T0800 \! -newermt 20111225T0800
Observe que a pergunta marcada como duplicada e, portanto, não pode responder diretamente, é por isso que estou postando aqui. Esta resposta é para responder à pergunta "precisa mover arquivos para uma pasta diferente com base na data de criação [duplicada]"
As respostas são razoáveis, mas houve algumas limitações com um comando puramente encontrar. Eu escrevi esse shell script para percorrer um diretório com tantos arquivos, que o sistema de arquivos estava engasgando com os metadados tentando executar um ls. Além disso, alguns sistemas * nix apresentam um erro de muitos argumentos ao executar ls.
O comando find é muito poderoso e comecei com os métodos listados, mas eu tinha tantos anos de dados nesse diretório que precisei passar todos os arquivos repetidamente. Isso produz um monte de desnecessário passado por cada arquivo. Tentei fazer uma tela por ano e executar várias descobertas, mas isso resultou em muitos erros em cada descoberta e os arquivos desapareceriam quando uma das descobertas a movia.
Meu script de shell move um arquivo para o diretório de destino, com um ano de 4 dígitos e um mês de 2 dígitos. Ele pode ser facilmente expandido para um dia de 2 dígitos, descomentando algumas linhas e comentando suas contrapartes. Eu acredito que é mais eficiente porque foi executar os movimentos em uma passagem de localização, de modo que vários comandos e passagens sobre o diretório são desnecessários.
#!/bin/bash
#We want to exit if there is no argument submitted
if [ -z "$1" ]
then
echo no input file
exit
fi
#destDir should be set to where ever you want the files to go
destDir="/home/user/destination"
#Get the month and year of modification time
#--format %y returns the modification date in the format:
# 2016-04-26 12:40:48.000000000 -0400
#We then take the first column, split by a white space with awk
date=`stat "$1" --format %y | awk '{ print $1 }'`
#This sets the year variable to the first column split on a - with awk
year=`echo $date | awk -F\- '{print $1 }'`
#This sets the month variable to the second column split on a - with awk
month=`echo $date | awk -F\- '{print $2 }'`
#This sets the day variable to the third column split on a - with awk
#This is commented out because I didn't want to add day to mine
#day=`echo $date | awk -F\- '{print $3 }'`
#Here we check if the destination directory with year and month exist
#If not then we want to create it with -p so the parent is created if
# it doesn't already exist
if [ ! -d $destDir/$year/$month ]
then
mkdir -p $destDir/$year/$month || exit
fi
#This is the same as above but utilizes the day subdirectory
#Uncommented this out and comment out the similar code above
#if [ ! -d $destDir/$year/$month/$day ]
#then
# mkdir -p $destDir/$year/$month$day || exit
#fi
#Echoing out what we're doing
#The uncommented is for just year/month and the commented line includes day
#Comment the first and uncomment the second if you need day
echo Moving $1 to $destDir/$year/$month
#echo Moving $1 to $destDir/$year/$month/$day
#Move the file to the newly created directory
#The uncommented is for just year/month and the commented line includes day
#Comment the first and uncomment the second if you need day
mv "$1" $destDir/$year/$month
#mv "$1" $destDir/$year/$month/$day
Uma vez salvo e tornado executável, você pode chamar esse script com os seguintes itens.
find /path/to/directory -type f -exec /home/username/move_files.sh {} \;
Você não precisa se preocupar em definir a opção newermt para find, pois tudo o que find está fornecendo é uma única execução por arquivo encontrado e o script toma todas as decisões.
Lembre-se de que, se você não selecionar -type f, os diretórios serão movidos e provavelmente causarão problemas. Você também pode usar -type d se estiver procurando mover apenas diretórios. Não definir o tipo quase certamente produzirá comportamento indesejado.
Lembre-se de que esse script foi adaptado às minhas necessidades. Você pode simplesmente usar minha construção como inspiração para um script mais adequado às suas necessidades. Obrigado!
Considerações: A eficiência do comando pode ser EXTREMAMENTE melhorada, permitindo que um número ilimitado de argumentos passe pelo script. Isso é relativamente fácil se você passar a variável $ @. Estender a funcionalidade disso nos permitiria usar a função -exec + do find ou alavancar xargs, por exemplo. Posso implementar isso rapidamente e melhorar minha própria resposta, mas isso é um começo.
Como essa foi uma sessão de script única, provavelmente há muitas melhorias que podem ser feitas. Boa sorte!