web-dev-qa-db-fra.com

Obtenir un mot spécifique en utilisant awk

Je suis en train de coder un script pour vérifier les bases de données mysql à l'aide d'un script bash. J'aimerais vérifier si le statut d'une table n'est pas "OK". Le nom de la table sera renvoyé et d'autres actions seront effectuées:

check.log

table1                 OK
table2                 Some error here
table3                 OK
table4                 OK
table5                 Another error
table6                 OK
table7                 Broken
table8                 A very long error which take a 2 lines
of multiple errors

check.sh

# check and repair tables
mysqlcheck -u $hostUser -p$hostPasswd --all-databases --check --auto-repair >> check.log

# grep tables status, should return OK
cat check.log | grep 'OK' | awk '{print $2}'| while read status; do

# if any table does not contain OK
if [ "$status" != "OK" ]
then
##### HERE WHERE I am stuck
#### It loops and return all the table

# grep to get the table name
cat check.log | grep 'OK' | awk '{print $1}'| while read table; do
echo $tblName' is BROKEN'
done
else
echo $tblName' is FINE'
fi

done

// here I need to mail the tables that have problems in one single mail

Vous recherchez une sortie comme:

tableName: error
tableName: error

table2: Some error here
table5: Another error
and so on

Ces lignes seront une sortie dans un fichier journal (result.txt)

Merci pour votre aide

1
Abu Rayane

Vous n'avez pas besoin de lire le fichier ligne par ligne à l'aide de bash. Awk le fait déjà. Par exemple, vous pouvez imprimer des entrées cassées en utilisant ce code

awk '$2!="OK"{print $0}'  check.log

Vous pouvez également simplement imprimer le nom de la table et utiliser cette commande pour créer un tableau, puis agir sur ceux-ci:

array=( $(awk '$2!="OK"{printf "%s ",$1 }'  check.log) )

Notez l'espace à côté de %s, c'est important.

Vous avez également mentionné que cette erreur peut être multiligne, tout comme pour table8. Nous voulons probablement éviter de jouer avec cela. Nous pouvons donc ajouter une coche pour que le champ 1 contienne un tableau Word.

$> array=( $(awk '$1~/table/ && $2!="OK"{printf "%s ",$1 }'  check.log) )      
$> echo ${array[@]}                                                            
table2 table5 table7 table8
$> echo ${array[0]}                                                            
table2
5

Comme le comportement par défaut de awk consiste à imprimer la ligne complète lorsqu'une condition True se produit, vous pouvez dire quelque chose d'aussi simple que ceci:

awk '$NF != "OK"' file

Ce qui retourne ce qui suit pour votre entrée donnée:

table2                 Some error here
table5                 Another error
table7                 Broken
table8                 A very long error which take a 2 lines
of multiple errors

Explication

  • NF représente le nombre de champs, donc $NF désigne le numéro de champ NF. C'est le dernier champ de chaque ligne.
  • En disant $NF != "OK" nous vérifions si le dernier champ de la ligne est "OK" ou pas. Si ce n'est pas le cas, la condition est vraie et la ligne est imprimée automatiquement.
3
fedorqui