ryzom_log_cleaner/clean_log.sh

232 lines
9.6 KiB
Bash
Executable file

#!/bin/bash
# Dernière révision : 2022/02/14
# Auteur : Zatalyz. Merci à YannK, Tycho et Glorf pour leurs nombreux conseils, les explications, l'aide et la patience !
# Licence CC0
# Ce script fait tout en un coup !
# 1) Splitter les logs de Ryzom qu'on lui file et les ranger dans les bons dossiers
# 2) Nettoyer et ne garder que les logs alentours
# Et ceci avec des lots de fichiers.
# ! Il faut que ce soit un seul perso par contre, ça ne veut pas marcher sinon !
# Attention, le script cherche en "dur" des années 2009 à 2025. Si les logs sont en dehors de ces dates, corrigez.
# Syntaxe : par défaut il va tout trouver et dire s'il y a un souci. Lancez simplement
# ./clean _log.sh
# Mais si besoin de préciser :
# ./clean _log.sh dossier_source dossier_tri dossier_alentours perso
# dossier_source = dossier des logs bruts au format ryzom
# dossier_tri = dossier de tri des fichiers bruts en un fichier par jour
# dossier_alentours = dossiers avec les fchiers de logs nettoyés pour ne garder que "alentours".
# perso = nom du perso
# 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). Cela se controle avec le fichier
#############
# Variables #
#############
# Canaux à analyser
channels="SAY\|SHOUT\|SYSTEM\/ZON"
# Vérification si le dossier source des logs existe et est renseigné
if [ -d "$1" ]
then foldersource="$1"
echo "Le dossier $foldersource existe, passons à la suite";
else foldersource="./sources_brutes"
if [ -d "$foldersource" ]
then echo "Le dossier $foldersource existe, passons à la suite";
else
mkdir -p "$foldersource"
echo "Le dossier $foldersource n'existait pas et été créé, déplacez les logs sources dedans";
exit
fi
fi
# Vérification si le dossier des logs bruts triés existe et sinon, le créer
if [ -d "$2" ]
then folderrawsorted="$2"
echo "Le dossier $folderrawsorted existe, passons à la suite";
else folderrawsorted="./sources_tri"
if [ -d "$folderrawsorted" ]
then echo "Le dossier $folderrawsorted existe, passons à la suite";
else mkdir -p "$folderrawsorted"
echo "Le dossier $folderrawsorted a été créé, passons à la suite";
fi
fi
# Vérifier si on a le dossier pour les logs alentours et sinon, le créer
if [ -d "$3" ]
then folderaround="$3"
echo "Le dossier $folderaround existe, passons à la suite";
else folderaround="./alentours"
if [ -d "$folderaround" ]
then echo "Le dossier $folderaround existe, passons à la suite";
else mkdir -p "$folderaround"
echo "Le dossier $folderaround a été créé, passons à la suite";
fi
fi
# Extraire le nom du persos depuis les noms de fichier
# TODO truc améliorable : arriver à gérer plusieurs persos
if [ -z "$4" ]
then
myfunc() {
basename -a "$foldersource"/* | cut -d_ -f2 | uniq
}
perso="$(myfunc)"
else perso="$4"
fi
# Avoir une variable avec la majuscule au pseudo
pseudo=${perso^}
# Dossiers nécessaires à faire le travail
tmpfolder="./tmplogfolder"
listrawlog="$tmpfolder/listrawlog.txt"
rawfolder="$tmpfolder/raw_logs"
yearfolder="$tmpfolder/year_logs"
monthfolder="$tmpfolder/month_logs"
dayfolder="$tmpfolder/day_logs"
tmparoundfolder="$tmpfolder/tmparoundfolder"
tmparoundfolder2="$tmpfolder/tmparoundfolder2"
# Comme ils sont détruits à la fin, on les recrée à chaque fois
mkdir -p "$tmpfolder" "$rawfolder" "$yearfolder" "$monthfolder" "$dayfolder" "$tmparoundfolder" "$tmparoundfolder2"
echo "Fichiers du personnage $pseudo prêts à être traités" ;
#############
# Split #
#############
# Cette partie sépare les logs bruts en 1 fichier de log par jour.
# 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 "$foldersource"/*
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
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é/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 "$folderrawsorted"/"$year"/"$month/"
# on déplace ces logs dans leur archive
mv "$dayfolder"/"$log" "$folderrawsorted"/"$year"/"$month"/"$log"
done
echo "Les fichiers ont été découpés et rangés"
#############
# Alentours #
#############
# Alors là, la misère... car on a des fichiers dans des sous-dossiers.
# Le plus simple : tout remettre dans un dossier en vrac et traiter à partir de là.
find "$folderrawsorted" -maxdepth 4 -name '*.log' -exec cp {} "$tmparoundfolder"/ \;
for mylog in "$tmparoundfolder/log"*.log
do
justnamelog() {
basename -s .log "$mylog"
}
namelog="$(justnamelog)"
sourcelog="$tmparoundfolder/${namelog}.log"
finallog="$tmparoundfolder2/${namelog}_alentours.txt"
#./1analyse_new_logryzom.sh $sourcelog $finallog
# Analyse des logs proprement dites
# Canaux à garder
# Alentours + Endroit où on est
grep "$channels" "$sourcelog" > templog.txt
# vire le timestamp de début des lignes. Garde le * si ça peut servir à nettoyer le sys.info..
cut -b 21- templog.txt > templog2.txt
# Enlève les couleurs des canaux
sed 's/@{[A-F0-9]\{4\}}//g' templog2.txt > templog3.txt
# enlever le nom des canaux :
sed -re 's:^\([A-Z/]+\) +\* +(.*)$:\1:' templog3.txt > templog4.txt
# laisser uniquement les phrases traduites (attention, ça peut être étrange)
sed -re 's#\{:[a-zA-Z]{2}:[^}]+\}@\{[[:space:]]##' templog4.txt > templog5.txt
# Remplacer "vous dites" par "Pseudo dit"
sed s/"Vous dites :"/"$pseudo dit :"/g templog5.txt > templog6.txt
sed s/"Vous criez"/"$pseudo crie :"/g templog6.txt > templog7.txt
# Si quelqu'un joue avec des caractères bizarres, ça remet tout d'aplomb
iconv -t utf-8 -c templog7.txt > "$finallog"
# Enlever les fichiers temporaires
rm templog*.txt
#echo "$sourcelog a été traité en tant que $finallog" #très bavard
done
# Retrier par année les fichiers nettoyés
for faround in $tmparoundfolder2/*.txt
do
# penser à compter les 10 caractères "alentours" pour que la variable marche
year=${faround: -24:4}
month=${faround: -19:2}
day=${faround: -16:2}
# On se fait une jolie variable qui imite la partie datée du nom des fichiers de log
finallogsorted=log_"$perso"_"${year}_${month}_${day}_alentours.txt"
# on créé le dossier de chaque mois s'il n'existe pas
mkdir -p "$folderaround"/"$year"/"$month/"
# on déplace ces logs dans leur archive
mv "$tmparoundfolder2"/"$finallogsorted" "$folderaround"/"$year"/"$month"/"$finallogsorted"
done
#############
# Dernier ménage #
#############
# Nettoyage
rm -r "$tmpfolder"
# On compte et vérifie les fichiers
count=$(find $folderrawsorted -maxdepth 4 -name '*.log' | wc -l)
echo "Les sources sont triées en $count fichiers dans $folderrawsorted. Contrôlez ce nombre sur controlline_$perso.txt"
countaround=$(find $folderaround -maxdepth 4 -name '*.txt' | wc -l)
echo "$countaround fichiers ont été nettoyés et rangés dans $folderaround. "
if [ "$count" = "$countaround" ]
then echo "Il semble y avoir le bon nombre de fichiers traités entre les bruts triés et les log nettoyés" ;
else echo "Attention, il y a une incohérence dans le nombre de fichiers traités entre les bruts triés et les log nettoyés" ;
fi