#!/bin/bash # Dernière révision : 2021/10/31 # Auteur : Zatalyz. Merci à YannK, Tycho et Glorf pour leurs nombreux conseils, les explications, l'aide et la patience ! # Licence CC0 # Ce script sépare les logs en 1 fichier de log par jour. # Il est prévu pour les logs du jeu Ryzom mais peut s'adapter à d'autres types de log (virer "pseudo !") # Mettre tous les logs en vrac dans le même dossier que le script, et lancer la moulinette. # La bonne commande à passer est # cmd ./dossiersource ./dossier final [nomperso] # Sans argument des variables par défaut seront utilisées. Le nom du perso peut être déduit des logs # Exemple : # ./split_log.sh ./logbrut/zatalyz/ ./final john # => les fichiers seront traités depuis ./logbrut/zatalyz/, et mis dans le dossier ./final sous le nom de log_john_année_mois_jour.txt # sans préciser "john", le nom des logs sera probablement celui de zatalyz, si les fichiers d'origine sont bien formatés comme log_zatalyz.txt ou log_zatalyz_*.txt # Le script range aussi les logs. # Attention ! Il laisse quelques fichiers dans le dossier courant. # Attention ! Gardez les logs originaux, dans quelques cas les lignes # ne sont pas analysées correctement (cas des retours à la ligne comme # dans les poèmes : la ligne ne commence plus par une date). ############# # Variables # ############# # Variables par défaut dans les checks : pouvoir les changer ? # Vérification si le dossier source des logs existe et est renseigné if [ -d "$1" ] then originalfolderlog="$1" else originalfolderlog="./logsource" fi # Vérification si le dossier final des logs existe et est renseigné if [ -d "$2" ] then finalfolder="$2" else finalfolder="./final_logs" fi # Vérification si un nom de perso est donné et sinon, extraction depuis les noms de fichier if [ -z "$3" ] then myfunc() { basename -a "$originalfolderlog"/* | cut -d_ -f2 | uniq } perso="$(myfunc)" else perso="$3" fi echo "Résultat final : nous partons de $originalfolderlog pour mettre les logs de $perso dans $finalfolder" # Variables des dossiers de travail tmpfolder="./tmplogfolder" listrawlog="$tmpfolder/listrawlog.txt" rawfolder="$tmpfolder/raw_logs" yearfolder="$tmpfolder/year_logs" monthfolder="$tmpfolder/month_logs" dayfolder="$tmpfolder/day_logs" ############# # Script # ############# # Vérifier si on a les dossiers temporaires de travail et sinon, les créer if [ -d "$rawfolder" ];then echo "Le dossier $rawfolder existe, passons à la suite"; else mkdir -p "$rawfolder" echo "Le dossier $rawfolder a été créé, passons à la suite"; fi if [ -d "$yearfolder" ];then echo "Le dossier $yearfolder existe, passons à la suite"; else mkdir -p "$yearfolder" echo "Le dossier $yearfolder a été créé, passons à la suite"; fi if [ -d "$monthfolder" ];then echo "Le dossier $monthfolder existe, passons à la suite"; else mkdir -p "$monthfolder" echo "Le dossier $monthfolder a été créé, passons à la suite"; fi if [ -d "$dayfolder" ];then echo "Le dossier $dayfolder existe, passons à la suite"; else mkdir -p "$dayfolder" echo "Le dossier $dayfolder a été créé, passons à la suite"; fi if [ -d "$finalfolder" ];then echo "Le dossier $finalfolder existe, passons à la suite"; else mkdir -p "$finalfolder" echo "Le dossier $finalfolder a été créé, passons à la suite"; fi # On ne travaille pas sur les fichiers sources. Jamais. # Parce qu'il y a parfois des blagues dans les logs, on nettoie l'encodage. for file in "$originalfolderlog"/* do originallog="$(basename $file)" cat "$file" | tr -d "\000-\010" | tr -d "\016-\037" > "$rawfolder"/"$originallog" done # on va faire un très gros fichier avec tous les logs. Évitez de l'ouvrir avec un éditeur de texte basique. cat "$rawfolder"/* > "$tmpfolder"/logcomplet_"$perso".txt #Et on va faire un fichier de controle donnant toutes les dates avec logs, et les lignes foireuses (genre chants) (à vérifier manuellement en cas de doute) cut -c 1-11 "$tmpfolder"/logcomplet_"$perso".txt | sort | uniq > controlline_"$perso".txt echo "$tmpfolder"/logcomplet_"$perso".txt et controlline_"$perso".txt créés for logname in "$tmpfolder"/logcomplet_"$perso".txt do # Vérification que les fichiers sont bien des fichiers, ce serait bête de planter le script pour un manque de vérification if [ -f "$logname" ] ; then echo "$logname est un fichier et va être traité" # On va faire un seul gros fichier par année for year in {2009..2025} ; do #echo "${year}" grep "^${year}/" "$logname" >> "$yearfolder"/"${year}".log # Effacer les fichiers vides [ -s "$yearfolder"/"${year}".log ] || rm -f "$yearfolder"/"${year}".log #echo "${year} traitée" # On vérifie si le fichier d'année existe et on ne traite que celles qui existent if [ -f "$yearfolder"/"${year}".log ] ; then # Puis on va faire un fichier par mois for month in {01..12} ; do # echo "${year}/${month} en cours" grep "^${year}/${month}" "$yearfolder"/"${year}".log > "$monthfolder"/"${year}_${month}".log [ -s "$monthfolder"/"${year}_${month}".log ] || rm -f "$monthfolder"/"${year}_${month}".log # On vérifie si le fichier année/mois existe et on ne traite que ceux qui existent if [ -f "$monthfolder"/"${year}_${month}".log ] ; then #echo "$monthfolder"/"${year}_${month}".log # Puis un fichier par jour for day in {01..31} ; do #echo "${year}/${month}/${day} en cours" grep "^${year}/${month}/${day}" "$monthfolder"/"${year}_${month}".log > "$dayfolder"/log_"$perso"_"${year}_${month}_${day}".log [ -s "$dayfolder"/log_"$perso"_"${year}_${month}_${day}".log ] || rm -f "$dayfolder"/log_"$perso"_"${year}_${month}_${day}".log #echo "${year}/${month}/${day} traité" done fi done fi done else echo "$logname n'est pas un fichier, il n'a pas été traité" fi done #Tri des fichiers dans des dossiers du type Dossier_trié/perso/année/mois/log.log # On récupère la date, en formattant comme pour les logs for f in $dayfolder/*.log do year=${f: -14:4} month=${f: -9:2} day=${f: -6:2} # On se fait une jolie variable qui imite la partie datée du nom des fichiers de log log=log_"$perso"_"${year}_${month}_${day}.log" # on créé le dossier de chaque mois dans les archives s'il n'existe pas mkdir -p "$finalfolder"/"$perso"/"$year"/"$month/" # on déplace ces logs dans leur archive mv "$dayfolder"/"$log" "$finalfolder"/"$perso"/"$year"/"$month"/"$log" done echo "Les fichiers ont été découpés et rangés" # Nettoyage #rm -r "$tmpfolder" echo "faites un rm -r $tmpfolder si le dossier tmp était bien JUSTE pour le script..." echo "Tout est bon. Contrôlez le nombre de fichiers entre $finalfolder et controlline_$perso.txt"