Bashスクリプトを使用してmysqlデータベースをチェックするスクリプトをコーディングしています。テーブルのステータスが「OK」ではないかどうかをチェックし、テーブル名を返し、いくつかのアクションを実行します。
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
次のような出力を探しています:
tableName: error
tableName: error
table2: Some error here
table5: Another error
and so on
これらの行は、ログファイル(result.txt)への出力になります
ご協力ありがとうございました
Bashを使用して1行ずつファイルを読み取る必要はありません。 Awkはすでにそれを行っています。たとえば、このコードを使用して壊れたエントリを印刷できます
awk '$2!="OK"{print $0}' check.log
テーブル名を出力し、そのコマンドを使用して配列を作成し、それらに基づいてアクションを実行することもできます。
array=( $(awk '$2!="OK"{printf "%s ",$1 }' check.log) )
%s
の隣のスペースに注意してください。これは重要です。
また、そのエラーは、table8の場合と同様に、複数行になります。私たちはおそらくそれを台無しにしたくないでしょう。そのため、フィールド1にもチェックを追加して、Wordテーブルを含めることができます。
$> array=( $(awk '$1~/table/ && $2!="OK"{printf "%s ",$1 }' check.log) )
$> echo ${array[@]}
table2 table5 table7 table8
$> echo ${array[0]}
table2
awk
のデフォルトの動作は、True条件が発生すると完全な行を出力することなので、次のような簡単なことを言うことができます。
awk '$NF != "OK"' file
これは、指定された入力に対して次を返します。
table2 Some error here
table5 Another error
table7 Broken
table8 A very long error which take a 2 lines
of multiple errors
NF
はフィールド数を表すため、$NF
はフィールド番号NF
を表します。つまり、すべての行の最後のフィールドです。$NF != "OK"
と言って、行の最後のフィールドが "OK
"かどうかを確認しています。そうでない場合、条件は真であり、行は自動的に印刷されます。