[LINUX] [Shell script] Calcule le temps écoulé à partir du fichier journal de START et END uniquement et le produit.

Je souhaite extraire les heures de début et de fin du fichier journal et les résumer dans un tableau

Supposons que le fichier journal suivant soit généré pour chaque travail qui charge la table

TABLENAME1_load.log


# iroiro
2020-08-28 00:01:00 DATA LOAD START !!!
2020-08-28 00:03:00 DATA LOAD NORMAL END !!!
# iroiro

TABLETAME2_load.log


# iroiro
2020-08-28 00:01:00 DATA LOAD START !!!
2020-08-28 00:10:00 DATA LOAD NORMAL END !!!
# iroiro

Je veux sortir ceci collectivement pour ce qui suit

result


JOBNAME      START     END       TIME(s)  TIME(m)
TABLENAME1   00:01:00  00:03:00  120      2
TABLENAME2   00:01:00  00:10:00  540      9
...

Méthode

Aperçu

Je ferai de mon mieux pour tout terminer avec shell!

INPUT

--Date (aaaammjj) --Fichier avec la liste des tâches de chargement (jobs.txt)

jobs.txt


TABLENAME1
TABLENAME2
TABLENAME3

--Fichier journal pour chaque tâche de chargement (TABLENAME_load. .log)

shell:TABLENAME1_load.20200828000100.log


# iroiro
2020-08-28 00:01:00 DATA LOAD START !!!
2020-08-28 00:10:00 DATA LOAD NORMAL END !!!
# iroiro

shell:TABLENAME2_load.20200828000100.log


# iroiro
2020-08-28 00:01:00 DATA LOAD START !!!
2020-08-28 00:13:00 DATA LOAD NORMAL END !!!
# iroiro

shell:TABLENAME3_load.20200828000200.log


# iroiro
2020-08-28 00:01:00 DATA LOAD START !!!
2020-08-28 00:20:00 DATA LOAD NORMAL END !!!
# iroiro

OUTPUT --Table de JOBNAME, START, END, TIME (s), TIME (m) --Trier par TIME afin que le travail qui constitue le goulot d'étranglement puisse être identifié

Flux de processus

P0.Fichier texte temporaire(JOBNAME, START, END, TIME(s), TIME(m)Vers l'en-tête)Créer
P1. jobs.Pour chaque tâche de chargement sur une ligne dans txt
    P1.1.Vérifiez s'il existe un fichier journal
    P1.2.Extraire la ligne avec les heures START et END du fichier journal
    P1.3.Extraire la partie horaire et démarrer\Affecter à une variable sous la forme de TEND
    P1.4. start,Stocker la fin dans une variable
    P1.5.temps écoulé(Secondes)Dans une variable
    P1.6.temps écoulé(Minutes)Dans une variable
    P1.7. 4,5,Stocker 6 sur une ligne de fichier texte
P1.8.Lorsque tous les travaux de chargement sont terminés, sortie dans l'ordre tabulaire dans l'ordre décroissant du temps écoulé
P1.9.Supprimer le fichier texte temporaire

Quoi utiliser

terminal


$ ls -l
sample.sh
jobs.txt
log/

$ cat jobs.txt
TABLENAME1
TABLENAME2
TABLENAME3

$ ls -l log/
20200828/
20200829/

$ ls -l log/20200828/
TABLENAME1_load.20200828000100.log
TABLENAME2_load.20200828000100.log
TABLENAME3_load.20200828000100.log
TABLENAME3_load.20200828000200.log

Code entier

sample.sh


#!/bin/sh

# Get the jobname from txt file
jobs=($(cat $2))

# Create tmp file with table header
echo JOBNAME START END 'TIME(s)' 'TIME(m)'  >> tmp_result.txt

for x in ${jobs[@]};
do
	if [ "$(ls log/$1/${x}_load.*)" != '' ]; then
		# Extract START and END from log file
		result=$(ls log/$1/${x}_load.* | tail -n 1 | xargs cat | grep "DATA LOAD" | cut -d' ' -f2 | echo $(tr '\n' '\t'))
		start=$(cut -d' ' -f 1 <<< $result)
		end=$(cut -d' ' -f 2 <<< $result)
		# Calc processing time
		time_s=$(expr `date -d$end +%s` - `date -d$start +%s`)
		time_m=$((time_s/60))
		# Save into txt file
		echo $x $start $end $time_s $time_m >> tmp_result.txt
	else
		echo 'there is no log file'
	fi
done 2> /dev/null

# Display result
(head -n +1 tmp_result.txt && tail -n +2 tmp_result.txt | sort -n -r -k 5) | column -t

# Remove tmp file
rm tmp_result.txt

résultat

――Il semble que vous puissiez connaître le temps écoulé pour chaque travail et comprendre quel travail doit être amélioré.

terminal


$ sh sample.sh 20200828 jobs.txt
JOBNAME     START     END       TIME(s)  TIME(m)
TABLENAME3  00:01:00  00:20:00  1140     19
TABLENAME2  00:01:00  00:13:00  720      12
TABLENAME1  00:01:00  00:10:00  540      9

Détails du traitement

Lisez jobs.txt et utilisez-le pour une déclaration

sample.sh


#!/bin/sh
# get the jobname from txt file
jobs=($(cat $1))
for x in ${jobs[@]};
do
        echo $x
done

terminal


$ sh sample.sh jobs.txt
TABLENAME1
TABLENAME2
TABLENAME3
P0. Créer un fichier texte temporaire (avec JOBNAME, START, END, TIME (s), TIME (m) comme en-tête)

sample.sh


echo JOBNAME START END 'TIME(s)' 'TIME(m)'  >> tmp_result.txt
P1.1 Vérifier s'il existe un fichier journal

sample.sh


#!/bin/sh
# --
for x in ${jobs[@]};
do
	if [ "$(ls log/$1/${x}_load.*)" != '' ]; then
		echo 'log file: ' $x
	else
		echo 'there is no log file'
	fi
done

terminal


$ sh sample.sh 20200828 jobs.txt
log file:  TABLENAME1
log file:  TABLENAME2
log file:  TABLENAME3
P1.2. Extraire la ligne avec les heures de début et de fin du fichier journal

--list fichier journal --S'il y a plusieurs fichiers journaux, prenez le dernier - tail -n 1 --Cattre le contenu - xargs cat

sample.sh


ls log/$1/${x}_load.* | tail -n 1 | xargs cat | grep "DATA LOAD" | cut -d' ' -f2 

terminal


$ sh sample.sh 20200828 jobs.txt
00:01:00 # TABLE1 START
00:10:00 # TABLE2 END
00:01:00 # TABLE2 START
00:13:00 # TABLE2 END
00:01:00 # TABLE3 START
00:20:00 # TABLE3 END

Vous pouvez maintenant obtenir `` HH: mm: dd '' de START et END pour chaque travail.

P1.3. Extraire la partie de temps et l'affecter à une variable au format START \ tEND

--Convertir les sauts de ligne en tabulations - tr '\n' '\t' --Substituer le résultat de pipe dans une variable - result=$(process | process | process)

sample.sh


for x in ${jobs[@]};
do
	if [ "$(ls log/$1/${x}_load.*)" != '' ]; then
		result=$(ls log/$1/${x}_load.* | tail -n 1 | xargs cat | grep "DATA LOAD" | cut -d' ' -f2 | echo $(tr '\n' '\t'))
		echo $result
	else
		echo 'there is no log file'
	fi
done

terminal


$ sh sample.sh 20200828 jobs.txt
00:01:00 00:10:00 # TABLENAME1
00:01:00 00:13:00 # TABLENAME2
00:01:00 00:20:00 # TABLENAME3
P1.4. Enregistrer le début et la fin dans les variables

sample.sh


	if [ "$(ls log/$1/${x}_load.*)" != '' ]; then
		result=$(ls log/$1/${x}_load.* | tail -n 1 | xargs cat | grep "DATA LOAD" | cut -d' ' -f2 | echo $(tr '\n' '\t'))
		start=$(cut -d' ' -f 1 <<< $result)
		end=$(cut -d' ' -f 2 <<< $result)
	else
		echo 'there is no log file'
	fi
P1.5. Le temps écoulé (secondes) est stocké dans une variable, P1.6. Le temps écoulé (minutes) est stocké dans une variable

sample.sh


time_s=$(expr `date -d$end +%s` - `date -d$start +%s`)
time_m=$((time_s/60))

terminal


$ expr `date -d'00:01:01' +%s` - `date -d'00:00:01' +%s`
60
P1.7. Stocker 4,5,6 sur une ligne de fichier texte

sample.sh


echo $x $start $end $time_s $time_m >> tmp_result.txt
P1.8. Lorsque tous les travaux de chargement sont terminés, sortie dans l'ordre tabulaire dans l'ordre décroissant du temps écoulé.

――La première ligne est l'en-tête, elle n'est donc pas soumise au tri. - head -n +1 tmp_result.txt && --Trier par ordre décroissant en utilisant la 5ème colonne TIME (m) '' comme clé à partir de la 2ème ligne. -tail -n +2 tmp_result.txt | sort -n -r -k 5 --Affichage au format tableau -column -t``

sample.sh


(head -n +1 tmp_result.txt && tail -n +2 tmp_result.txt | sort -n -r -k 5) | column -t
P1.9. Supprimer le fichier texte temporaire

sample.sh


rm tmp_result.txt 

en conclusion

Je voudrais commencer avec le script shell, et si vous avez des opinions sur la façon de mieux écrire, je vous serais reconnaissant si vous pouviez me le faire savoir.

référence

Recommended Posts

[Shell script] Calcule le temps écoulé à partir du fichier journal de START et END uniquement et le produit.
Spécifiez les positions de début et de fin des fichiers à inclure avec qiitap
Donnez une date et une heure à la commande d'historique et collectez les fichiers d'historique de tous les utilisateurs avec un script