Obtenha uma palavra específica usando o awk

1

Estou codificando um script para verificar bancos de dados mysql usando o script bash, gostaria de verificar se o status de uma tabela não é 'OK', retornará o nome da tabela e executará mais algumas açõ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

Procurando por uma saída como:

tableName: error
tableName: error

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

Estas linhas serão uma saída em um arquivo de log (result.txt)

Obrigado pelo seu apoio

    
por Abu Rayane 30.03.2016 / 03:33

2 respostas

5

Você não precisa ler o arquivo linha por linha usando o bash. O Awk já faz isso. Por exemplo, você pode imprimir entradas quebradas usando este código

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

Você também pode imprimir o nome da tabela e usar esse comando para criar uma matriz e, em seguida, agir sobre eles:

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

Observe o espaço ao lado de %s , isso é importante.

Você mencionou também que o erro pode ser multilinha, assim como para table8. Nós provavelmente queremos evitar mexer com isso. Portanto, podemos adicionar uma verificação também para o campo 1 conter uma tabela de palavras.

$> array=( $(awk '$1~/table/ && $2!="OK"{printf "%s ",$1 }'  check.log) )      
$> echo ${array[@]}                                                            
table2 table5 table7 table8
$> echo ${array[0]}                                                            
table2
    
por Sergiy Kolodyazhnyy 30.03.2016 / 04:34
3

Como o comportamento padrão de awk é imprimir a linha completa quando ocorre uma condição True, você pode dizer algo simples assim:

awk '$NF != "OK"' file

Que retorna o seguinte para sua entrada:

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

Explicação

  • NF representa o número de campos, então $NF representa o número de campo NF . Ou seja, o último campo em todas as linhas.
  • Dizer que $NF != "OK" está verificando se o último campo na linha é " OK " ou não. Se não for, a condição é verdadeira e a linha é impressa automaticamente.
por fedorqui 30.03.2016 / 09:00