I am trying to run some queries from bash. first, how can I connect once and perform SELECT queries from different dbs? and the following code does not work.
> $LOG_FILE
> $SQL_FILE
for sam in $db
do
echo "USE ${sam}; SELECT login, FORMAT(SUM(PROFIT), 2) AS PROFIT FROM MT4_TRADES WHERE CLOSE_TIME >= '2016-12-01' AND CLOSE_TIME < '2016-02-29' AND CMD IN (0 , 1) GROUP BY LOGIN LIMIT 10;" >> ${SQL_FILE}
done
while read line
do
echo "beginning: `date "+%F %T"`" | tee -a ${LOG_FILE}
out=`echo "$line" | mysql -N --host=${Host} --user=${User} --password=${Passwd} 2>&1`
echo "$out" >> ${LOG_FILE}
if [[ ${?} -eq 0 ]]; then
echo "RESULTS FETCHED: `date "+%F %T"`" | tee -a ${LOG_FILE}
else
echo "FETCHING RESULT failed" | tee -a ${LOG_FILE}
exit 1
fi
done < ${SQL_FILE}
Related
I'm looking to run a command a given number of times in an Alpine Linux docker container which features the /bin/ash shell.
In Bash, this would be
bash-3.2$ for i in {1..3}
> do
> echo "number $i"
> done
number 1
number 2
number 3
However, the same syntax doesn't seem to work in ash:
> docker run -it --rm alpine /bin/ash
/ # for i in 1 .. 3
> do echo "number $i"
> done
number 1
number ..
number 3
/ # for i in {1..3}
> do echo "number $i"
> done
number {1..3}
/ #
I had a look at https://linux.die.net/man/1/ash but wasn't able to easily find out how to do this; does anyone know the correct syntax?
I ended up using seq with command substitution:
/ # for i in $(seq 10)
> do echo "number $i"
> done
number 1
number 2
number 3
number 4
number 5
number 6
number 7
number 8
number 9
number 10
Simply like with bash or shell:
$ ash -c "for i in a b c 1 2 3; do echo i = \$i; done"
output:
i = a
i = b
i = c
i = 1
i = 2
i = 3
Another POSIX compatible alternative, which does not use potentially slow expansion, is to use
i=1; while [ ${i} -le 3 ]; do
echo ${i}
i=$(( i + 1 ))
done
i am using this code for getting my desired output for automation purpose but always face error relate to if condition........
mysql --login-path=local << EOF >/home/test.sql
use testdb;
if ([$(date +%m) -eq 1] | [$(date +%m) -eq 3] | [$(date +%m) -eq 5] | [$(date +%m) -eq 7] | [$(date +%m) -eq 8] | [$(date +%m) -eq 10] | [$(date +%m) -eq 12])
then
select COUNT(id) from xxx where app_id ='ABC' and date(creation_date) between '$(date +%F -d "tomorrow -31 days")' and '$(date +%F)' and action='AUTH' ;
elseif [$(date +%m) -eq 2 ]
then
select COUNT(id) from xxx where app_id ='ABC' and date(creation_date) between '$(date +%F -d "tomorrow -28 days")' and '$(date +%F)' and action='AUTH' ;
else
select COUNT(id) from xxx where app_id ='ABC' and date(creation_date) between '$(date +%F -d "tomorrow -30 days")' and '$(date +%F)' and action='AUTH' ;
fi
EOF
please help me to resolve this query.or correct this code i am new in shell script .
Thanks in advance!!!!!!!
Mysql won't understand if ..else shell syntax and so you will need to execute mysql within each if, else block with -e for execution e.g:
...
elseif [ "$(date +%m)" -eq 2 ]
then
mysql --login-path=local -e "use testdb;select COUNT(id) from xxx where app_id ='ABC' and date(creation_date) between '$(date +%F -d "tomorrow -28 days")' and '$(date +%F)' and action='AUTH' ;" >> /home/test.sql
else
...
Pretend I have a MySQL table test that looks like:
+----+---------------------+
| id | value |
+----+---------------------+
| 1 | Hello World |
| 2 | Foo Bar |
| 3 | Goodbye Cruel World |
+----+---------------------+
And I execute the query SELECT id, value FROM test.
How would I assign each column to a variable in Bash using read?
read -a truncates everything after the first space in value:
mysql -D "jimmy" -NBe "SELECT id, value FROM test" | while read -a row;
do
id="${row[0]}"
value="${row[1]}"
echo "$id : $value"
done;
and output looks like:
1 : Hello
2 : Foo
3 : Goodbye
but I need it to look like:
1 : Hello World
2 : Foo Bar
3 : Goodbye Cruel World
I'm aware there are args I could pass to MySQL to format the results in table format, but I need to parse each value in each row. This is just a simplified example of my problem.
Use individual fields in the read loop instead of the array:
mysql -D "jimmy" -NBe "SELECT id, value FROM test" | while read -r id value;
do
echo "$id : $value"
done
This will make sure that id will be read into the id field and everything else would be read into the value field - that's how read behaves when input has more fields than the number of variables being read into. If there are more columns to be read, using a delimiter (such as #) that doesn't clash with actual data would help:
mysql -D "jimmy" -NBe "SELECT CONCAT(id, '#', value, '#', column3) FROM test" | while IFS='#' read -r id value column3;
do
echo "$id : $value : $column3"
done
You can do this, also avoid piping a command to a while read loop if possible to avoid creating a subshell.
while read -r line; do
id=$(echo $line | awk '{print $1}')
value=$(echo $line | awk '{print $1=""; print $0}'|sed ':a;N;$!ba;s/\n/ /g'| sed 's/^[ \t]*//g')
echo "ID: $id"
echo "VALUE: $value"
done< <(mysql -D "jimmy" -NBe "SELECT id, value FROM test")
If you want to store all the id's and values in an array for later use, you can modify it to look like this.
#!/bin/bash
declare -A -g arr
while read -r line; do
id=$(echo $line | awk '{print $1}')
value=$(echo $line | awk '{print $1=""; print $0}'|sed ':a;N;$!ba;s/\n/ /g'| sed 's/^[ \t]*//g')
arr[$id]=$value
done< <(mysql -D "jimmy" -NBe "SELECT id, value FROM test")
for key in "${!arr[#]}"; do
echo "$key: ${arr[$key]}"
done
Which gives you this output
dumbledore#ansible1a [OPS]:~/tmp/tmp > bash test.sh
1: Hello World
2: Foo Bar
3: Goodbye Cruel World
I am trying to run sql query in if statement. Here is my shell script
#!/bin/bash
var="select col1, col2 from table_name where condition;"
count=$(ping -c 4 192.168.7.204 | awk -F',' '{ print $2 }' | awk '{ print $1 }')
if [ $count -eq 0 ]; then
mysql -h 192.168.7.204 -u username -ppassword db_name<<EOFMYSQL
$var
EOFMYSQL
fi
But it shows me an error
./test.sh: line 18: warning: here-document at line 12 delimited by end-of-file (wanted `EOFMYSQL')
./test.sh: line 19: syntax error: unexpected end of file
The here-document sentinelEOFMYSQL has to be up against the left margin, not indented:
var="select col1, col2 from table_name where condition;"
count=$(ping -c 4 192.168.7.204 | awk -F',' '{ print $2 }' | awk '{ print $1 }')
if [ $count -eq 0 ]; then
mysql -h 192.168.7.204 -u username -ppassword db_name <<EOFMYSQL
$var
EOFMYSQL
fi
If you change the <<EOFMYSQL to <<-EOFMYSQL you can indent it, as long as you use only tabs and not spaces.
See the manual.
Here I have a database msmdb which contains a table emp.
I am trying to display the values in that table using a bash script but there comes an error saying command not found (at line 8 after the echo).
USER_NAME=root
USER_PWD=prj
DB_NAME=msmdb
flag=0
delimiter="a3f4g52"
echo "select id ,'"$delimiter"', name,'"$delimiter"', city, '"$delimiter"', salary FROM emp" | \
mysql -u $USER_NAME --password=$USER_PWD --database=$DB_NAME | \
while read row ;
do
if [ $flag == 0 ]; then
flag=1
else
name=` echo $row | \
awk -F "$delimiter" '{print $1}' | \
sed -e 's/ *$//' | sed 's/^ *//'`
age=` echo $row | \
awk -F "$delimiter" '{print $2}' | \
sed -e 's/ *$//' | sed 's/^ *//'`
bornPlace=`echo $row | \
awk -F "$delimiter" '{print $3}' | \
sed -e 's/ *$//' | sed 's/^ *//'`
echo ">$name<"
echo ">$age<"
echo ">$bornPlace<"
fi
done
Any idea about what might be the reason for error ??
In line 8 you have a space following the linebreak (\) therefore the linebreak doesn't work.
Got The Script working properly ......
Just had to remove ' \ ' from the program and it worked.
The Correct bash script is
USER_NAME=root
USER_PWD=prj
DB_NAME=msmdb
flag=0
delimiter="a3f4g52"
echo "select id ,'"$delimiter"', name,'"$delimiter"', city, '"$delimiter"', salary FROM emp" |
mysql -u $USER_NAME --password=$USER_PWD --database=$DB_NAME |
while read row ;
do
if [ $flag == 0 ]; then
flag=1
else
name=` echo $row | awk -F "$delimiter" '{print $1}' | sed -e 's/ *$//' | sed 's/^ *//'`
age=` echo $row | awk -F "$delimiter" '{print $2}' | sed -e 's/ *$//' | sed 's/^ *//'`
bornPlace=` echo $row | awk -F "$delimiter" '{print $3}' | sed -e 's/ *$//' | sed 's/^ *//'`
echo ">$name<"
echo ">$age<"
echo ">$bornPlace<"
fi
done