1 | #!/bin/sh |
---|
2 | ##set -xv |
---|
3 | # stephane.senesi 'at' meteo.fr, CNRM-GAME/GMGEC, mars-avril 2010 |
---|
4 | doc="\nScript d'analyse des fichiers d'un repertoire pour y trouver des formes \n\ |
---|
5 | de nom de fichier avec dates, les dates, et des sequences de dates. \n\ |
---|
6 | On synthetise la |
---|
7 | \n\n\t Syntaxe : $(basename $0) [-d] [-v/q] [-R] [-Z] dir [-S subdir] [-I maxyear]\n\n\ |
---|
8 | L'option -R permet d'inclure les sous-repertoires\n\ |
---|
9 | L'option -Z permet de verifier que les tailles des fichiers mensuels sont identiques par mois\n\ |
---|
10 | dir permet de decrire le repertoire selectionne : . par defaut \n\ |
---|
11 | -S subdir permet de decrire les sous-repertoires selectionnes : \*/Output par exemple\n\ |
---|
12 | -I maxyear ne traite que les dates inferieures ou egales a maxyear. Toutes les dates par defaut\n\ |
---|
13 | Les formes de dates identifiables sont illustrees dans l'exemple obtenu par \n\ |
---|
14 | \t$(basename $0) -exemple\n\ |
---|
15 | la valeur retournee est le nombre de formes de noms de fichier qui presentent des trous\n |
---|
16 | Si l option -Z est precisee, le code retour y ajoute le nombre de mois avec tailles differentes.\n |
---|
17 | -q pour n avoir aucun message / -v pour avoir les patterns et erreurs a l ecran \n |
---|
18 | -d pour activer l echo des commandes \n |
---|
19 | Exemples :\n |
---|
20 | check_expe_files_size.sh SRF/Output/MO # verification des noms du repertoire SRF/Output/MO\n |
---|
21 | check_expe_files_size.sh -Z SRF/Output/MO # verification des noms et des tailles des fichiers du repertoire\n |
---|
22 | check_expe_files_size.sh -R -S \"*/Output\" # verification des noms des fichiers pour toute une simulation IPSL\n |
---|
23 | check_expe_files_size.sh -Z -R -S \"*/Output\" # verification des noms et des tailles des fichiers pour toute une simulation IPSL\n |
---|
24 | check_expe_files_size.sh -I 1949 -R -S \"*/Output\" # verification jusuque a l annee 1949 incluse des noms des fichiers pour une simulation IPSL\n |
---|
25 | " |
---|
26 | #La presence d'une annee+mois impose la presence de l'annee entiere |
---|
27 | [ $# -eq 0 ] && echo -e $doc && exit -1 |
---|
28 | |
---|
29 | debugflag=0 |
---|
30 | quiet=0 |
---|
31 | exemple=0 |
---|
32 | recursion=0 |
---|
33 | examsize=0 |
---|
34 | dir=. |
---|
35 | subdir= |
---|
36 | maxyear=9999 |
---|
37 | maxyearp1=9999 |
---|
38 | |
---|
39 | #--------------------------------------------- |
---|
40 | while [ $# -ne 0 ] |
---|
41 | do |
---|
42 | case $1 in |
---|
43 | -h|--help|-help) |
---|
44 | echo -e $doc |
---|
45 | exit -1 ;; |
---|
46 | -e|-exemple) |
---|
47 | exemple=1 |
---|
48 | # exemple de formes de dates reconnues par ce script. La liste ci-dessous est aussi |
---|
49 | # utilisee lors des tests du script |
---|
50 | cat<<-EOF > /tmp/$$.ldir |
---|
51 | MONEXP_20000101_20000131_1M_histmth.nc |
---|
52 | MONEXP_20000101_20000131_1M_histmthNMC.nc |
---|
53 | MONEXP_20000201_20000228_1M_histmth.nc |
---|
54 | MONEXP_20000201_20000228_1M_histmthNMC.nc |
---|
55 | MONEXP_20000301_20000331_1M_histmth.nc |
---|
56 | MONEXP_20000301_20000331_1M_histmthNMC.nc |
---|
57 | MONEXP_20000401_20000430_1M_histmth.nc |
---|
58 | MONEXP_20000401_20000430_1M_histmthNMC.nc |
---|
59 | MONEXP_20000501_20000531_1M_histmth.nc |
---|
60 | MONEXP_20000501_20000531_1M_histmthNMC.nc |
---|
61 | MONEXP_20000601_20000630_1M_histmth.nc |
---|
62 | MONEXP_20000601_20000630_1M_histmthNMC.nc |
---|
63 | MONEXP_20000701_20000731_1M_histmth.nc |
---|
64 | MONEXP_20000701_20000731_1M_histmthNMC.nc |
---|
65 | MONEXP_20000801_20000831_1M_histmth.nc |
---|
66 | MONEXP_20000801_20000831_1M_histmthNMC.nc |
---|
67 | MONEXP_20000901_20000930_1M_histmth.nc |
---|
68 | MONEXP_20000901_20000930_1M_histmthNMC.nc |
---|
69 | MONEXP_20001001_20001031_1M_histmth.nc |
---|
70 | MONEXP_20001001_20001031_1M_histmthNMC.nc |
---|
71 | MONEXP_20001101_20001130_1M_histmthNMC.nc |
---|
72 | MONEXP_20001201_20001231_1M_histmth.nc |
---|
73 | MONEXP_20001201_20001231_1M_histmthNMC.nc |
---|
74 | |
---|
75 | EOF |
---|
76 | echo -e "\nExample : with this directory content\n" |
---|
77 | cat /tmp/$$.ldir |
---|
78 | echo -e "\n\nYou would get :\n\n" |
---|
79 | break;; |
---|
80 | -d|--debug) |
---|
81 | set -x |
---|
82 | debugflag=1 |
---|
83 | shift ;; |
---|
84 | -q|--quiet) |
---|
85 | quiet=1 |
---|
86 | shift ;; |
---|
87 | -v|--verbose) |
---|
88 | quiet=0 |
---|
89 | shift ;; |
---|
90 | -R|-r|--r) |
---|
91 | recursion=1 |
---|
92 | shift ;; |
---|
93 | -Z|-z|--z) |
---|
94 | examsize=1 |
---|
95 | shift ;; |
---|
96 | -S|-s|--s) |
---|
97 | subdir=$2 |
---|
98 | shift 2 ;; |
---|
99 | -I|-i|--i) |
---|
100 | maxyear=$2 |
---|
101 | (( maxyearp1 = maxyear + 1 )) |
---|
102 | shift 2 ;; |
---|
103 | *) |
---|
104 | dir=$1 |
---|
105 | break ;; |
---|
106 | esac |
---|
107 | done |
---|
108 | |
---|
109 | [ $quiet = 0 ] && echo quiet : $quiet recursion : $recursion - examsize : $examsize - dir - $dir -- subdir $subdir-- maxyearp1 : $maxyearp1 |
---|
110 | if [ $exemple = 0 ] ; then |
---|
111 | [ ! -d $dir ] && echo "verif_expe_files : missing directory $dir "&& exit |
---|
112 | ( cd $dir |
---|
113 | if [ $recursion = O ] ; then ls > /tmp/$$.ldir ; [ $examsize = 1 ] && ls -l > /tmp/$$.size # Cas "normal" : on liste les entrees du repertoire et ls long |
---|
114 | else find ./$subdir -type f > /tmp/$$.ldir ; [ $examsize = 1 ] && find ./$subdir -type f -exec ls -l {} \; >/tmp/$$.size # Cas de listage recursif des fichiers |
---|
115 | fi |
---|
116 | ) |
---|
117 | fi |
---|
118 | ###head /tmp/$$.ldir ; head /tmp/$$.size ; rm /tmp/$$* |
---|
119 | # For debugging purpose ... |
---|
120 | #head -n 2 /tmp/$$.ldir > /tmp/$$.aa ; mv /tmp/$$.aa /tmp/$$.ldir |
---|
121 | #set -x |
---|
122 | # On remplace les / en ~ dans la liste des fichiers |
---|
123 | cat /tmp/$$.ldir | tr "/" "~" > /tmp/$$.aa ; mv /tmp/$$.aa /tmp/$$.ldir |
---|
124 | [ -f /tmp/$$.size ] && cat /tmp/$$.size | tr "/" "~" > /tmp/$$.aa && mv /tmp/$$.aa /tmp/$$.size |
---|
125 | # On deduit de la liste des fichiers des patterns de annee+mois, annee, intervalles de date ... |
---|
126 | sed -r \ |
---|
127 | -e 's/[0-5][0-9]{3}[01][0-9]/YYMM/g' \ |
---|
128 | -e 's/YYMM01_YYMM(28|29|30|31)/YYmmdd_YYmmdd/g' \ |
---|
129 | /tmp/$$.ldir | sort -u > /tmp/$$.lpat |
---|
130 | # Ci-dessus, il faudrait compter les nb d'occ de chqaue pattern pour signaler et |
---|
131 | # ne pas retenir ceux qui n'apparaissent qu'une fois (sauf les decennaux ?) |
---|
132 | # On ote les patterns sans date du tout |
---|
133 | sed -i -e '/YY/!d' /tmp/$$.lpat |
---|
134 | # On rend compte des patterns identifies |
---|
135 | #echo "Formes de fichier identifiees: " ; awk '{printf "\t%s\n",$1}' /tmp/$$.lpat |
---|
136 | # Une fonction pour associer un nom de fichier a chaque pattern : on remplace les / par des ~ |
---|
137 | tmpfic (){ |
---|
138 | echo -n "/tmp/$$." ; echo $1 | tr "/" "_" |
---|
139 | } |
---|
140 | # Pour chaque pattern, on liste les dates pertinentes: annees de debut et fin pour les |
---|
141 | # intervalles d'annees, ou annee ou annee+mois pour les autres |
---|
142 | cat /dev/null > /tmp/$$.dates |
---|
143 | #set -x |
---|
144 | while read pattern ; do |
---|
145 | if [ $(echo $pattern | grep "YYmmdd_YYmmdd") ] ; then |
---|
146 | # On transforme le pattern pour mettre une sequences |
---|
147 | # de capture des annees de debut et fin d'intervalle |
---|
148 | p2=$(echo $pattern | sed -e 's/YYmmdd_YYmmdd/([0-5][0-9]{3}[01][0-9])01_[0-5][0-9]{3}[01][0-9](28|29|30|31)/g' ) |
---|
149 | |
---|
150 | # On balaye le repertoire avec le(s) pattern(s) transforme(s) pour capturer les annees |
---|
151 | grep -E $p2 /tmp/$$.ldir | sed -r -e "s/$p2/\1/g" >> /tmp/$$.$pattern.tmp |
---|
152 | fi |
---|
153 | sort -n -u /tmp/$$.$pattern.tmp > /tmp/$$.$pattern.list |
---|
154 | # Si la liste des date (annees ou annes+mois) pour le pattern est |
---|
155 | # de taille > 1, on l'integre a la liste generale des dates |
---|
156 | # en supprimant au prealable les dates isolees |
---|
157 | # ... ca reste a faire |
---|
158 | cat /tmp/$$.$pattern.list | cut -c 1-4 >> /tmp/$$.dates |
---|
159 | done < /tmp/$$.lpat |
---|
160 | # Fonction pour completer et rendre sequentielle une liste d'annees (une par ligne) |
---|
161 | force_sequence (){ |
---|
162 | awk '{ |
---|
163 | if (NR==1) {avant=$1; print $1} |
---|
164 | else { for (i=avant+1 ; i<=$1 ; i++) printf "%04i\n", i}}' |
---|
165 | } |
---|
166 | sort -u /tmp/$$.dates > /tmp/$$.toutes_dates |
---|
167 | # On enleve les trous dans la liste des dates |
---|
168 | force_sequence < /tmp/$$.toutes_dates > /tmp/$$.tmp ; sort -u /tmp/$$.tmp > /tmp/$$.toutes_dates |
---|
169 | # Fonction d'analyse de sequences de nombres (annees, ou annees+mois |
---|
170 | # On transforme les series continues a a+1 a+2....b (a raison d'un par |
---|
171 | # ligne) en : "a-b" |
---|
172 | sequence (){ |
---|
173 | awk -v pas=${1:-1} '{ |
---|
174 | if (NR==1) {avant=$1;nb=1; printf "%s",$1} |
---|
175 | else { |
---|
176 | suivant=avant+pas |
---|
177 | # Pour les nombres sur 6 chiffres, on suppose que c est du YYYMM |
---|
178 | # et on gere le passage de decembre a janvier |
---|
179 | if ((length(avant)==6) && (substr(avant,5,2)=="12")) |
---|
180 | { avant4=substr(avant,1,4) ; suivant=sprintf("%4d01",avant4+1)} |
---|
181 | if ($1 > suivant) { |
---|
182 | if (nb>1) printf "-%s",avant |
---|
183 | nb=1 ; printf ", %s",$1} |
---|
184 | else { nb=nb+1 } |
---|
185 | avant=$1 }} |
---|
186 | END { if (nb >1) printf "-%s\n",avant ; else print ""} ' |
---|
187 | } |
---|
188 | [ $quiet = 0 ] && echo $(wc -l /tmp/$$.ldir | cut -d \ -f 1) files proceeded. |
---|
189 | [ $quiet = 0 ] && echo -n "Years occurring : " && sequence 1 < /tmp/$$.toutes_dates |
---|
190 | # on ne garde que les annees inferieures a maxyear |
---|
191 | sed "/$maxyearp1/"',$d' </tmp/$$.toutes_dates >/tmp/$$.toutes_dates_maxyear |
---|
192 | [ $quiet = 0 ] && echo -n "Years tested : " && sequence 1 < /tmp/$$.toutes_dates_maxyear |
---|
193 | mv /tmp/$$.toutes_dates_maxyear /tmp/$$.toutes_dates |
---|
194 | # On liste tous les mois qui doivent etre presents (au motif qu'une annee est presente) |
---|
195 | > /tmp/$$.toutes_dates_et_mois |
---|
196 | while read an ; do |
---|
197 | i=1 |
---|
198 | while [ $i -le 12 ] ; do |
---|
199 | printf "%s%02d\n" ${an} $i >> /tmp/$$.toutes_dates_et_mois |
---|
200 | i=$(( i + 1 )) |
---|
201 | done |
---|
202 | done < /tmp/$$.toutes_dates |
---|
203 | # Pour chaque pattern, on analyse si toutes les dates sont presentes en bon nombre (decennie, an, an+mois) |
---|
204 | touch /tmp/$$.synthese |
---|
205 | [ $quiet = 0 ] && echo "File name patterns and holes (if any) :" |
---|
206 | #set -x |
---|
207 | while read pattern ; do |
---|
208 | [ `echo $pattern | grep -E "(YYmmdd_YYmmdd)"` ] && pas=1 && \ |
---|
209 | join -v 1 /tmp/$$.toutes_dates_et_mois /tmp/$$.$pattern.list > /tmp/$$.$pattern.manques |
---|
210 | sequence $pas < /tmp/$$.$pattern.manques > /tmp/$$.$pattern.synthese |
---|
211 | truepattern=$(echo $pattern | tr "~" "/") |
---|
212 | [ $quiet = 0 ] && printf "%80s : " $truepattern && cat /tmp/$$.$pattern.synthese |
---|
213 | cat /tmp/$$.$pattern.synthese >> /tmp/$$.synthese |
---|
214 | done < /tmp/$$.lpat |
---|
215 | |
---|
216 | rep=$(wc -w /tmp/$$.synthese | tail -1 | cut -d \ -f 1) |
---|
217 | if [ $examsize = 0 ] ; then rm /tmp/$$* ; exit $rep ; fi |
---|
218 | |
---|
219 | # taille des fichiers |
---|
220 | cat /dev/null > /tmp/$$.dates |
---|
221 | #set -x |
---|
222 | while read pattern ; do |
---|
223 | i=1 |
---|
224 | while [ $i -le 12 ] ; do |
---|
225 | mois=$(printf "%02d\n" $i) |
---|
226 | if [ $(echo $pattern | grep "YYmmdd_YYmmdd") ] ; then |
---|
227 | # On transforme le pattern pour mettre une sequences |
---|
228 | # avec le mois courant |
---|
229 | px=$(echo $pattern | sed -e "s/YYmmdd_YYmmdd/([0-5][0-9]{3})${mois}01_[0-5][0-9]{3}${mois}(28|29|30|31)/g" ) |
---|
230 | |
---|
231 | # On balaye le repertoire avec le(s) pattern(s) transforme(s) pour capturer les tailles des fichiers de ce mois |
---|
232 | grep -E $px /tmp/$$.size | awk '{print $5}' | sort -u >/tmp/$$.$pattern.size_${mois} |
---|
233 | # On garde les infos s il n y a pas une taille unique |
---|
234 | for size in $(cat /tmp/$$.$pattern.size_${mois}) ; do |
---|
235 | grep -E $px /tmp/$$.size | grep " "${size}" " | tr "~" "/" >>/tmp/$$.$pattern.files_${mois}.${size} |
---|
236 | done |
---|
237 | fi |
---|
238 | i=$(( i + 1 )) |
---|
239 | done |
---|
240 | done < /tmp/$$.lpat |
---|
241 | |
---|
242 | [ $quiet = 0 ] && echo |
---|
243 | [ $quiet = 0 ] && echo "Size verification per month (if different) :" |
---|
244 | # Pour chaque pattern, on liste la taille des fichiers de chaque mois |
---|
245 | touch /tmp/$$.synthese_size |
---|
246 | while read pattern ; do |
---|
247 | truepattern=$(echo $pattern | tr "~" "/") |
---|
248 | [ $quiet = 0 ] && printf "%80s : " $truepattern |
---|
249 | if [ `echo $pattern | grep -E "(YYmmdd_YYmmdd)"` ] ; then |
---|
250 | RESULT="" |
---|
251 | for i in 1 2 3 4 5 6 7 8 9 10 11 12 ; do |
---|
252 | mois=$(printf "%02d\n" $i) |
---|
253 | if [ $(wc -l /tmp/$$.$pattern.size_${mois} | cut -d " " -f 1) = 1 ] ; then |
---|
254 | RESULT="$RESULT " |
---|
255 | else |
---|
256 | # special case for february , we accept 2 different sizes for february for leap year |
---|
257 | if [[ $i == 2 && $(wc -l /tmp/$$.$pattern.size_${mois} | cut -d " " -f 1) = 2 ]] ; then |
---|
258 | # est ce qu il y a des mois de 29 jours? si non souci reel |
---|
259 | if [ $( grep 0229 /tmp/$$.$pattern.files_02.* 1>/dev/null 2>&1 ) ] ; then |
---|
260 | RESULT="$RESULT \033[1;31m[$mois]\033[m" |
---|
261 | cat /tmp/$$.$pattern.size_${mois} >> /tmp/$$.synthese_size |
---|
262 | else |
---|
263 | RESULT="$RESULT " |
---|
264 | fi |
---|
265 | else |
---|
266 | RESULT="$RESULT \033[1;31m[$mois]\033[m" |
---|
267 | cat /tmp/$$.$pattern.size_${mois} >> /tmp/$$.synthese_size |
---|
268 | fi |
---|
269 | fi |
---|
270 | done |
---|
271 | [ $quiet = 0 ] && echo -e $RESULT |
---|
272 | fi |
---|
273 | done < /tmp/$$.lpat |
---|
274 | |
---|
275 | # affichage des details |
---|
276 | while read pattern ; do |
---|
277 | first=0 |
---|
278 | i=1 |
---|
279 | truepattern=$(echo $pattern | tr "~" "/") |
---|
280 | while [ $i -le 12 ] ; do |
---|
281 | mois=$(printf "%02d\n" $i) |
---|
282 | if [ $(echo $pattern | grep "YYmmdd_YYmmdd") ] ; then |
---|
283 | # si on a plus de 2 tailles de fichiers pour ce mois, on liste le nombre de fichiers par taille et les 3 premiers |
---|
284 | # cas special pour fevrier qui accepte 2 tailles differentes si 1 pour les 28 et l autre pour les 29 |
---|
285 | if [ $(wc -l /tmp/$$.$pattern.size_${mois} | cut -d " " -f 1) != 1 ] ; then |
---|
286 | if [[ $i == 2 && $(wc -l /tmp/$$.$pattern.size_${mois} | cut -d " " -f 1) == 2 ]] ; then |
---|
287 | # est ce qu il y a des mois de 29 jours? sinon souci reel |
---|
288 | if [ $( grep 0229 /tmp/$$.$pattern.files_02* 1>/dev/null 2>&1 ) ] ; then |
---|
289 | if [[ ${first} == 0 ]] ; then printf "Details %73s : \n" $truepattern ; first=1 ; fi |
---|
290 | echo mois : ${mois} |
---|
291 | for size in $( cat /tmp/$$.$pattern.size_${mois} ) ; do |
---|
292 | head -1 /tmp/$$.$pattern.files_${mois}.${size} |
---|
293 | done |
---|
294 | fi |
---|
295 | else |
---|
296 | if [[ ${first} == 0 ]] ; then printf "Details %73s : \n" $truepattern ; first=1 ; fi |
---|
297 | echo mois : ${mois} |
---|
298 | for size in $( cat /tmp/$$.$pattern.size_${mois} ) ; do |
---|
299 | head -1 /tmp/$$.$pattern.files_${mois}.${size} |
---|
300 | done |
---|
301 | fi |
---|
302 | fi |
---|
303 | fi |
---|
304 | i=$(( i + 1 )) |
---|
305 | done |
---|
306 | done < /tmp/$$.lpat |
---|
307 | |
---|
308 | |
---|
309 | rep=$(wc -w /tmp/$$.synthese /tmp/$$.synthese_size | tail -1 | sed -e 's/total//' -e 's/ //g' ) |
---|
310 | |
---|
311 | # reste a analyser par annee en sus de par pattern, pour presenter le plus clair |
---|
312 | # Penser a forunir l'option d'imposer des patterns et des annees en entree |
---|
313 | [ $debugflag = 0 ] && rm -f /tmp/$$.* /tmp/$$.ldir |
---|
314 | exit $rep |
---|
315 | # Changes |
---|
316 | # - 20 april 2010 : add handling of pattern year1-year2, which is a generalization of decades |
---|
317 | # - janvier 2011 : suppression des caracteres accentues |
---|
318 | # mise en place pour prefix de type libIGCM / IPSL |
---|
319 | # ajout de la verification des tailles des fichiers mensuels |
---|
320 | # ajout des options -d -q/-v -R -S subdir -I maxyear |
---|
321 | |
---|
322 | |
---|