Formato de saída do MySQL no Bash Script

4

Estou escrevendo um script bash em que estou usando a consulta mysql nesse script, no qual o formato que estou obtendo é bem diferente.

Consulta:

root@debian:~# mysql -u root -ptoor super_market -h 0 -e "select * from items;" 
+---------+------------+--------+-------------+-------+
| item_id | item_name  | weight | brand       | price |
+---------+------------+--------+-------------+-------+
|       1 | Milk       |   2.00 | Nestle      |  2.00 |
|       2 | Cheese     |   2.50 | Amul        |  6.00 |
|       3 | Chips      |  25.00 | Lays        |  3.00 |
|       4 | Coke       |   5.00 | Coke Cola   |  3.50 |
|       5 | Engage     |   5.00 | Deo         |  3.50 |
|       6 | Engage     |   5.00 | Deo         |  3.50 |
|       7 | Ear phones |   4.00 | Skull Candy | 32.30 |
+---------+------------+--------+-------------+-------+

formatado usando o comando coluna -t o formato de saída está sendo alinhado

root@debian:~# mysql -u root -ptoor super_market -h 0 -e "select * from items;" | column -t
item_id  item_name  weight  brand   price
1        Milk       2.00    Nestle  2.00
2        Cheese     2.50    Amul    6.00
3        Chips      25.00   Lays    3.00
4        Coke       5.00    Coke    Cola   3.50
5        Engage     5.00    Deo     3.50
6        Engage     5.00    Deo     3.50
7        Ear        phones  4.00    Skull  Candy  32.30

Script Bash o script bash que eu tentei usando o comando acima

root@debian:~# cat test
#!/bin/bash

while read -r output;
do
    echo $output | awk '{print $4}'
    #do something
done< <(mysql -u root -ptoor super_market -h 0 -e "select * from items;" | sed 1d |column -t)

saída

root@debian:~# ./test
Nestle
Amul
Lays
Coke
Deo
Deo
4.00

Mas a saída esperada :

Nestle
Amul
Lays
Coke Cola
Deo
Deo
Skull Candy

Sim! você pode dizer usar selecione marca nos itens . Isto é, por exemplo, em tempo real, estou usando um comando bem diferente.

Alguma dica ou ajuda?

    
por Prasanna Ranganthan 02.06.2016 / 00:25

4 respostas

2

saída do mysql é delimitada por tabulações. column substitui tabulações por espaços que quebram sua entrada.

#!/bin/bash

while read -r output;
do
    # use double quotes with "$output" to avoid conversion
    # of tabs to spaces and set awk's Field Separator to "\t"
    echo "$output" | awk -F"\t" '{print $4}'
    #do something
done< <(mysql -u root -ptoor super_market -h 0 -e "select * from items;" | sed 1d)

teste executado:

root@c2:~# mysql -u root -ptoor super_market -h 0 -e "select * from items;"
+---------+------------+--------+-------------+-------+
| item_id | item_name  | weight | brand       | price |
+---------+------------+--------+-------------+-------+
|       1 | Milk       |      2 | Nestle      |     2 |
|       2 | Cheese     |    2.5 | Amul        |     6 |
|       3 | Chips      |     25 | Lays        |     3 |
|       4 | Coke       |      5 | Coke Cola   |   3.5 |
|       5 | Engage     |      5 | Deo         |   3.5 |
|       6 | Engage     |      5 | Deo         |   3.5 |
|       7 | Ear phones |      4 | Skull Candy |  32.3 |
+---------+------------+--------+-------------+-------+
root@c2:~# ./test.sh 
Nestle
Amul
Lays
Coke Cola
Deo
Deo
Skull Candy
root@c2:~# 
    
por 02.06.2016 / 01:24
0

Você não precisa usar a ferramenta column , pois sua tabela está realmente pronta. Tente usar awk com o delimitador comum | .

Você pode fazer o seguinte na sua echo line

echo "$output" | awk -F'|' '{print $5}'

Então termina como

#!/bin/bash

while read -r output;
do
    echo $output | awk '{print $5}'
    #do something
    done< <(mysql -u root -ptoor super_market -h 0 -e "select * from items;" | sed '1,2d')
    
por 02.06.2016 / 01:39
0

Esta é uma solução muito suja e hacky, mas você pode usar o ponto ( . ) como separador, pois você tem números de ponto flutuante em cada lado. Você pode chamar awk da seguinte forma

awk -F '.' '{a=gensub(/^[0-9]*\s*|\s*[0-9]*$/,"","g",$2); print a}'

no script e ele deve imprimir apenas a marca.

Haverá espaços estranhos no meio das marcas, mas você pode estender o script awk para lidar com isso também:

awk -F '.' '{a=gensub(/^[0-9]*\s*|\s*[0-9]*$/,"","g",$2); b=gensub(/\s+/," ","g",a); print b}'
A função awk do gensub é uma ferramenta muito poderosa para esses tipos de problemas. Embora esse exemplo específico seja sujo, acredito que saber usar gensub ( manual é bastante decente ) permitirá que você resolva problemas similares com facilidade.

O acima é GNU awk ( gawk ) específico. Os sistemas Unix old school ( AIX , HP-UX ) não possuem gawk . Engraçado, por alguma razão desconhecida, debian também não possui gawk por padrão. debian tem mawk como o padrão awk instalado. Aqui está uma versão mawk :

awk -F '.' '{gsub(/^[0-9]*\s*|\s*[0-9]*$/,"",$2); gsub(/\s+/," ",$2); print $2}'

mawk não tem gensub , só tem gsub (substituição global). gsub é muito inferior a gensub porque não retorna sua substituição. Se você estiver usando debian e precisar de awk , muitas vezes, eu recomendo strongmente a instalação do gawk (ele está no repositório principal).

    
por 02.06.2016 / 01:25
0

Use mysql com o -t flag, para obter a saída que você obtém de uma consulta no mysql diretamente como sua saída bash.

Depois, você pode usar sed ou awk para limpar os delimitadores, remover as linhas horizontais e as | 's.

    
por 23.01.2017 / 14:10