1 | #!/bin/sh |
---|
2 | ##set -xv |
---|
3 | # stephane.senesi 'at' meteo.fr, CNRM-GAME/GMGEC, mars-avril 2010 |
---|
4 | doc="\nScript d'analyse d'une liste de fichiers pour y trouver des formes \n\ |
---|
5 | de nom de fichier avec dates, les dates, et des sequences de dates. \n\ |
---|
6 | \n\n\t Syntaxe : $(basename $0) [-d] [-v/q] file_liste \n\n\ |
---|
7 | -q pour n avoir aucun message / -v pour avoir les patterns et erreurs a l ecran \n |
---|
8 | -d pour activer l echo des commandes \n |
---|
9 | On separe par simulation\n |
---|
10 | Exemple :\n |
---|
11 | $(basename $0) file_list # verification des noms de la liste contenue dans file_list\n |
---|
12 | " |
---|
13 | #La presence d'une annee+mois impose la presence de l'annee entiere |
---|
14 | [ $# -eq 0 ] && echo -e $doc && exit -1 |
---|
15 | |
---|
16 | debugflag=0 |
---|
17 | quiet=0 |
---|
18 | |
---|
19 | #--------------------------------------------- |
---|
20 | while [ $# -ne 0 ] |
---|
21 | do |
---|
22 | case $1 in |
---|
23 | -h|--help|-help) |
---|
24 | echo -e $doc |
---|
25 | exit -1 ;; |
---|
26 | -d|--debug) |
---|
27 | set -x |
---|
28 | debugflag=1 |
---|
29 | shift ;; |
---|
30 | -q|--quiet) |
---|
31 | quiet=1 |
---|
32 | shift ;; |
---|
33 | -v|--verbose) |
---|
34 | quiet=0 |
---|
35 | shift ;; |
---|
36 | *) |
---|
37 | liste=$1 |
---|
38 | break ;; |
---|
39 | esac |
---|
40 | done |
---|
41 | |
---|
42 | ## on separe les simus : |
---|
43 | for simu in $( awk -F/ '$4 != "dods" && /SORTIES_CPL_IPSL/ {print $6} $4 != "dods" && /IGCM_OUT/ {print $9} ' $liste | sort -u ) ; do |
---|
44 | |
---|
45 | grep /$simu/ $liste > /tmp/$$.ldir |
---|
46 | |
---|
47 | echo $simu |
---|
48 | |
---|
49 | ###head /tmp/$$.ldir ; head /tmp/$$.size ; rm /tmp/$$* |
---|
50 | # For debugging purpose ... |
---|
51 | #head -n 2 /tmp/$$.ldir > /tmp/$$.aa ; mv /tmp/$$.aa /tmp/$$.ldir |
---|
52 | #set -x |
---|
53 | # On remplace les / en ~ dans la liste des fichiers |
---|
54 | cat /tmp/$$.ldir | tr "/" "~" > /tmp/$$.aa ; mv /tmp/$$.aa /tmp/$$.ldir |
---|
55 | # On deduit de la liste des fichiers des patterns de annee+mois, annee, intervalles de date ... |
---|
56 | sed -r \ |
---|
57 | -e 's/[0-2][0-9]{3}[01][0-9]/YYMM/g' \ |
---|
58 | -e 's/YYMM01_YYMM(28|29|30|31)/YYmmdd_YYmmdd/g' \ |
---|
59 | -e 's/YYMM(28|29|30|31)/YYmmdd/g' \ |
---|
60 | /tmp/$$.ldir | sort -u > /tmp/$$.lpat |
---|
61 | # Ci-dessus, il faudrait compter les nb d'occ de chqaue pattern pour signaler et |
---|
62 | # ne pas retenir ceux qui n'apparaissent qu'une fois (sauf les decennaux ?) |
---|
63 | # On ote les patterns sans date du tout |
---|
64 | sed -i -e '/YY/!d' /tmp/$$.lpat |
---|
65 | # On rend compte des patterns identifies |
---|
66 | #echo "Formes de fichier identifiees: " ; awk '{printf "\t%s\n",$1}' /tmp/$$.lpat |
---|
67 | # Une fonction pour associer un nom de fichier a chaque pattern : on remplace les / par des ~ |
---|
68 | tmpfic (){ |
---|
69 | echo -n "/tmp/$$." ; echo $1 | tr "/" "_" |
---|
70 | } |
---|
71 | # Pour chaque pattern, on liste les dates pertinentes: annees de debut et fin pour les |
---|
72 | # intervalles d'annees, ou annee ou annee+mois pour les autres |
---|
73 | cat /dev/null > /tmp/$$.dates |
---|
74 | #set -x |
---|
75 | while read pattern ; do |
---|
76 | if [ $(echo $pattern | grep "YYmmdd_YYmmdd") ] ; then |
---|
77 | # On transforme le pattern pour mettre une sequences |
---|
78 | # de capture des annees de debut et fin d'intervalle |
---|
79 | p2=$(echo $pattern | sed -e 's/YYmmdd_YYmmdd/([0-2][0-9]{3}[01][0-9])01_[0-2][0-9]{3}[01][0-9](28|29|30|31)/g' ) |
---|
80 | |
---|
81 | # On balaye le repertoire avec le(s) pattern(s) transforme(s) pour capturer les annees |
---|
82 | grep -E $p2 /tmp/$$.ldir | sed -r -e "s/$p2/\1/g" >> /tmp/$$.$pattern.tmp |
---|
83 | else |
---|
84 | p2=$(echo $pattern | sed -e 's/YYmmdd/([0-2][0-9]{3}[01][0-9])(28|29|30|31)/g' ) |
---|
85 | # On balaye le repertoire avec le(s) pattern(s) transforme(s) pour capturer les annees |
---|
86 | grep -E "$p2" /tmp/$$.ldir | sed -r -e "s/$p2/\1/g" >> /tmp/$$.$pattern.tmp |
---|
87 | fi |
---|
88 | sort -n -u /tmp/$$.$pattern.tmp > /tmp/$$.$pattern.list |
---|
89 | # Si la liste des date (annees ou annes+mois) pour le pattern est |
---|
90 | # de taille > 1, on l'integre a la liste generale des dates |
---|
91 | # en supprimant au prealable les dates isolees |
---|
92 | # ... ca reste a faire |
---|
93 | cat /tmp/$$.$pattern.list | cut -c 1-4 >> /tmp/$$.dates |
---|
94 | done < /tmp/$$.lpat |
---|
95 | # Fonction pour completer et rendre sequentielle une liste d'annees (une par ligne) |
---|
96 | force_sequence (){ |
---|
97 | awk '{ |
---|
98 | if (NR==1) {avant=$1; print $1} |
---|
99 | else { for (i=avant+1 ; i<=$1 ; i++) print i}}' |
---|
100 | } |
---|
101 | sort -u /tmp/$$.dates > /tmp/$$.toutes_dates |
---|
102 | # On enleve les trous dans la liste des dates |
---|
103 | force_sequence < /tmp/$$.toutes_dates > /tmp/$$.tmp ; sort -u /tmp/$$.tmp > /tmp/$$.toutes_dates |
---|
104 | # Fonction d'analyse de sequences de nombres (annees, ou annees+mois |
---|
105 | # On transforme les series continues a a+1 a+2....b (a raison d'un par |
---|
106 | # ligne) en : "a-b" |
---|
107 | sequence (){ |
---|
108 | awk -v pas=${1:-1} '{ |
---|
109 | if (NR==1) {avant=$1;nb=1; printf "%s",$1} |
---|
110 | else { |
---|
111 | suivant=avant+pas |
---|
112 | # Pour les nombres sur 6 chiffres, on suppose que c est du YYYMM |
---|
113 | # et on gere le passage de decembre a janvier |
---|
114 | if ((length(avant)==6) && (substr(avant,5,2)=="12")) |
---|
115 | { avant4=substr(avant,1,4) ; suivant=sprintf("%4d01",avant4+1)} |
---|
116 | if ($1 > suivant) { |
---|
117 | if (nb>1) printf "-%s",avant |
---|
118 | nb=1 ; printf ", %s",$1} |
---|
119 | else { nb=nb+1 } |
---|
120 | avant=$1 }} |
---|
121 | END { if (nb >1) printf "-%s\n",avant ; else print ""} ' |
---|
122 | } |
---|
123 | [ $quiet = 0 ] && echo $(wc -l /tmp/$$.ldir | cut -d \ -f 1) files proceeded. |
---|
124 | [ $quiet = 0 ] && echo -n "Years occurring : " && sequence 1 < /tmp/$$.toutes_dates |
---|
125 | # On liste tous les mois qui doivent etre presents (au motif qu'une annee est presente) |
---|
126 | > /tmp/$$.toutes_dates_et_mois |
---|
127 | while read an ; do |
---|
128 | i=1 |
---|
129 | while [ $i -le 12 ] ; do |
---|
130 | printf "%s%02d\n" ${an} $i >> /tmp/$$.toutes_dates_et_mois |
---|
131 | i=$(( i + 1 )) |
---|
132 | done |
---|
133 | done < /tmp/$$.toutes_dates |
---|
134 | # Pour chaque pattern, on analyse si toutes les dates sont presentes en bon nombre (decennie, an, an+mois) |
---|
135 | touch /tmp/$$.synthese |
---|
136 | [ $quiet = 0 ] && echo "File name patterns and holes (if any) :" |
---|
137 | #set -x |
---|
138 | while read pattern ; do |
---|
139 | [ `echo $pattern | grep -E "(YYmmdd_YYmmdd|YYmmdd)"` ] && pas=1 && \ |
---|
140 | join -v 1 /tmp/$$.toutes_dates_et_mois /tmp/$$.$pattern.list > /tmp/$$.$pattern.manques |
---|
141 | sequence $pas < /tmp/$$.$pattern.list > /tmp/$$.$pattern.synthese |
---|
142 | truepattern=$(echo $pattern | tr "~" "/") |
---|
143 | [ $quiet = 0 ] && printf "%80s : " $truepattern && cat /tmp/$$.$pattern.synthese |
---|
144 | cat /tmp/$$.$pattern.synthese >> /tmp/$$.synthese |
---|
145 | done < /tmp/$$.lpat |
---|
146 | |
---|
147 | # reste a analyser par annee en sus de par pattern, pour presenter le plus clair |
---|
148 | # Penser a forunir l'option d'imposer des patterns et des annees en entree |
---|
149 | rm -f /tmp/$$.* /tmp/$$.ldir |
---|
150 | done |
---|
151 | |
---|
152 | # Changes |
---|
153 | # - 20 april 2010 : add handling of pattern year1-year2, which is a generalization of decades |
---|
154 | # - janvier 2011 (MA Foujols) : suppression des caracteres accentues |
---|
155 | # mise en place pour prefix de type libIGCM / IPSL |
---|
156 | # ajout de la verification des tailles des fichiers mensuels |
---|
157 | # ajout des options -d -q/-v -R -S subdir -I maxyear |
---|
158 | # - juin 2011 (MA Foujols) : adapte a une liste des fichiers par exemple detruits sur bande du CCRT |
---|
159 | |
---|