Unix - como buscar arquivos com base na parte de um nome de arquivo que é data

3

Digamos que eu tenha arquivos como

AA_XX_20111208
AA_XX_20111207
AA_XX_20111206
AA_XX_20111205
AA_XX_20111204
AA_XX_20111203

Então, usando a parte da data, Como posso buscar arquivos anteriores de 2 meses?

Por exemplo este mês é fevereiro Eu preciso buscar todos os arquivos referentes a janeiro e dezembro. e para o mês de março, devo buscar arquivos de janeiro e fevereiro Isso tem que acontecer a cada mês.

para o mês de fevereiro eu preciso de arquivos de dezembro e janeiro

AA_XX_20121208
AA_XX_20121207
AA_XX_20121206

... assim por diante

AA_XX_20130108
AA_XX_20130107
AA_XX_20130106

... assim por diante

    
por JK23 06.02.2013 / 08:15

4 respostas

2

Supondo que você tenha data do GNU, essa função fornecerá todas as datas dos dois meses anteriores:

dates_in_previous_two_months () { 
    for month_delta in 0 1; do
        # get the last day of a previous month
        day=$(date -d "$(date +%Y-%m-01) -$month_delta month -1 day" +%Y%m%d)
        until [[ $day == *00 ]]; do
            echo $day
            ((day--))
        done
    done
}

Para qualquer dia no mês de fevereiro de 2013, isso retorna:

20130131
20130130
20130129
[... and so on until ...]
20121203
20121202
20121201

Em março, as datas serão retornadas de 20130228 para 20130101

Você poderia usá-lo como:

for date in $(dates_in_previous_two_months); do
    "fetch" AA_XX_$date
done

ou

dates_in_previous_two_months | xargs -I{} "fetch" AA_XX_{}
    
por 06.02.2013 / 13:00
1

Você pode usar o comando find . O comando a seguir listará todos os arquivos modificados nos últimos 60 dias

find . -name 'AA_XX_*' -mtime -60

Aqui está o shell script para conseguir o que você quer, mas eu concordo que não é uma solução limpa. Eu, pessoalmente, não gosto deste código desajeitado, mas então ele vai funcionar para você, por enquanto

#!/usr/local/bin/bash

YEAR='date +%Y'
MONTH='date +%m'
DATE='date +%d'

if [ $MONTH = 01 ]; then
    OLDEST='expr $YEAR - 1'11010000
    NEWEST='expr $YEAR - 1'12312359
elif [ $MONTH = 02 ]; then
    OLDEST='expr $YEAR - 1'12010000
    echo $YEAR
    NEWEST="$YEAR"01312359
else
    case $MONTH in
            03)
            OLDEST=$YEAR0'expr $MONTH - 2'010000
            if [ $YEAR%4 = 0 ]; then
                    DATE=29
            else
                    DATE=28
            fi
            NEWEST=$YEAR0'expr $MONTH - 1'"$DATE"2359;;

            04|06|09|11)
            OLDEST=$YEAR0'expr $MONTH - 2'010000
            NEWEST=$YEAR0'expr $MONTH - 1'312359;;

            07|08|10|12)
            OLDEST=$YEAR0'expr $MONTH - 2'010000
            NEWEST=$YEAR0'expr $MONTH - 1'302359;;
        esac
fi

echo $OLDEST
echo $NEWEST

touch -t $OLDEST oldest
touch -t $NEWEST newest

find . -name 'AA_XX_*' -newer oldest ! -newer newest > temp.txt
    
por 06.02.2013 / 09:53
0

Assim?

cp source/AA_XX_$(date -d "2 months ago" +%04Y%02m)* source/AA_XX_$(date -d "1 month ago" +%04Y%02m)* destination/
    
por 06.02.2013 / 10:35
0

Este mês com o ano prefixado é $(date +%Y%m) . O mês passado é previous_month_1=$(date -d '1 month ago' +%Y%m) com a data GNU (ou seja, no Linux ou Cygwin não integrado) e o mês anterior é previous_month_2=$(date -d '2 months ago' +%Y%m) . em outras implementações, elas são dadas por

this_month=$(date +%Y%m)
case $this_month in
  *01) previous_month_1=$((this_month-89)); previous_month_2=$((previous_month-1));;
  *02) previous_month_1=$((this_month-1)); previous_month_2=$((previous_month-89));;
  *) previous_month_1=$((this_month-1)); previous_month_2=$((previous_month-1));;
esac

Agora, para corresponder a todos os arquivos existentes com data dos dois meses anteriores:

fetch "AA_XX_$previous_month_1"?? "AA_XX_$previous_month_2"??

(Substitua fetch pelo comando que você deseja executar nesses arquivos.) Se um mês não tiver nenhum arquivo correspondente, o padrão será mantido inalterado:

filter_month () {
  case $1 in *'??') return;; esac
  fetch "$@"
}
filter_month "$previous_month_1"??
filter_month "$previous_month_2"??

Se você quiser buscar todos os arquivos correspondentes aos dias do mês, você precisará de alguma magia de data GNU (não descrita aqui) ou de alguma lógica bissexual.

filter_month () {
  case $1 in
    *0[13578]|*1[02]) n=31;;
    *0[469]|*11) n=30;;
    *0002) if [ $((${1%????} %4)) -eq 0 ]; then n=29; else n=28; fi;;
    *02) if [ $((${1%??} %4)) -eq 0 ]; then n=29; else n=28; fi;;
  esac
  while [ $n -gt 0 ]; do
    d=$n
    if [ $d -lt 10 ]; then d=0$d; fi
    fetch "AA_XX_$1$d"
  fi
}
filter_month "$previous_month_1"
filter_month "$previous_month_2"
    
por 07.02.2013 / 01:44