bash scripting for mysqldump - bash

i use the following code to download all mysql database in a different file and not in one file (like --all-databases) and put them in the /backup/mysql folder
#!/bin/bash
mysqldump=`which mysqldump`
echo $mysqldump
mkdir /backup/mysql/$(date '+%d-%b-%Y')
echo "creating folder for current date done"
for line in "$(mysqlshow |cut -f1 -d"-" | cut -c 3- | cut -f1 -d" ")"
do
$mysqldump $line > /backup/mysql/$(date '+%d-%b-%Y')/"$line"
echo "$line\n"
done
I used the cut pipes to remove dashes and empty space before and at the end of the database name and it gave me what I want.
The problem is at line 13 according to bash but with no more details. Any ideas what I'm doing wrong?

mysqlshow output format
+---------------------+
| Databases |
+---------------------+
| information_schema |
| gitlabhq_production |
| mysql |
| performance_schema |
| phpmyadmin |
| test |
+---------------------
Your script doesn't manage the first 3 lines nor the last one, so you $line variable is invalid.
Solution
mysql | tail -n +4 | head -n -1 | tr -d '| '
tail -n +4: skip first four lines (may need adjustement);
head -n -1: ignore last line ;
tr -d '| ': remove pipe and space.
Advices
quotes your variables ;
use $() instead of backtick ;
don't use for i in $(ls *.mp3).
read How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?
Better solution
Instead of a for loop you should use a while with a Process Substitution:
while read -r db; do
echo "[$db]";
done < <(mysqlshow -u root -p | tail -n +3 | head -n -1 | tr -d ' |' )

Related

How to get nth line of a file in bash?

I want to extract from a file named datax.txt the second line being :
0/0/0/0/0/0 | 0/0/0/0/0/0 | 0/0/0/0/0/0
And then I want to store in 3 variables the 3 sequences 0/0/0/0/0/0.
How am I supposed to do?
Read the 2nd line into variables a,b and c.
read a b c <<< $(awk -F'|' 'NR==2{print $1 $2 $3}' datax)
the keys is to split the problem in two:
you want to get the nth line of a file -> see here
you want to split a line in chunks according to a delimiter -> that's the job of many tools, cut is one of them
For future questions, be sure to include a more complete dataset, here is one for now. I changed a bit the second line so that we can verify that we got the right column:
f.txt
4/4/4/4/4/4 | 4/4/4/4/4/4 | 4/4/4/4/4/4
0/0/0/0/a/0 | 0/0/0/0/b/0 | 0/0/0/0/c/0
8/8/8/8/8/8 | 8/8/8/8/8/8 | 8/8/8/8/8/8
8/8/8/8/8/8 | 8/8/8/8/8/8 | 8/8/8/8/8/8
Then a proper script building on the two key actions described above:
extract.bash
file=$1
target_line=2
# get the n-th line
# https://stackoverflow.com/questions/6022384/bash-tool-to-get-nth-line-from-a-file
line=$(cat $file | head -n $target_line | tail -1)
# get the n-th field on a line, using delimiter '|'
var1=$(echo $line | cut --delimiter='|' --fields=1)
echo $var1
var2=$(echo $line | cut --delimiter='|' --fields=2)
echo $var2
var3=$(echo $line | cut --delimiter='|' --fields=3)
echo $var3
aaand:
$ ./extract.bash f.txt
0/0/0/0/a/0
0/0/0/0/b/0
0/0/0/0/c/0
Please try the following:
IFS='|' read a b c < <(sed -n 2P < datax | tr -d ' ')
Then the variables a, b and c are assigned to each field of the 2nd line.
You can use sed to print a specific line of a file, so for your example on the second line:
sed -n -e 2p ./datax
Set the output of the sed to be a variable:
Var=$(sed -n -e 2p ./datax)
Then split the string into the 3 variables you need:
A="$(echo $Var | cut -d'|' -f1)"
B="$(echo $Var | cut -d'|' -f2)"
C="$(echo $Var | cut -d'|' -f3)"

Shell Script do while flow

I have a script whose content is like:
#!/bin/bash
DB_FILE='pgalldump.out'
echo $DB_FILE
DB_NAME=''
egrep -n "\\\\connect\ $DB_NAME" $DB_FILE | while read LINE
do
DB_NAME=$(echo $LINE | awk '{print $2}')
STARTING_LINE_NUMBER=$(echo $LINE | cut -d: -f1)
STARTING_LINE_NUMBER=$(($STARTING_LINE_NUMBER+1))
TOTAL_LINES=$(tail -n +$STARTING_LINE_NUMBER $DB_FILE | \
egrep -n -m 1 "PostgreSQL\ database\ dump\ complete" | \
head -n 1 | \
cut -d: -f1)
tail -n +$STARTING_LINE_NUMBER $DB_FILE | head -n +$TOTAL_LINES > /backup/$DB_NAME.sql
done
I know what it is doing. But i have a doubt about the flow of do while in this case. At line egrep -n "\\\\connect\ $DB_NAME" $DB_FILE | while read LINE will egrep runs first or while . Because DB_NAME is empty at start of code.
Could anyone please explain the flow of do while in this case.

Get first match from a CURL grep call

Objective:
I'm trying to write a script that will fetch two URLs from a GitHub release page and do something different with each one.
So far:
Here's what I've got so far.
λ curl -s https://api.github.com/repos/mozilla-iot/gateway/releases/latest | grep "browser_download_url.*tar.gz" | cut -d : -f 2,3 | tr -d \"
This will return the following:
"https://github.com/mozilla-iot/gateway/releases/download/0.8.1/gateway-8c29257704ddb021344bdaaa790909a0eacf3293bab94e02859828a6fd9b900a.tar.gz"
"https://github.com/mozilla-iot/gateway/releases/download/0.8.1/node_modules-921bd0d58022aac43f442647324b8b58ec5fdb4df57a760e1fc81a71627f526e.tar.gz"
I want to be able to create some directories, pull in the first one, navigate in the directories from the newly pulled zip after extracting it, and then pull in the second.
fetching the first line is easy by piping the output to head -n1. for solving your problem, you need more than just fetching the first URL of the cURL output. give this a try:
#!/bin/bash
# fetch your URLs
answer=`curl -s https://api.github.com/repos/mozilla-iot/gateway/releases/latest | grep "browser_download_url.*tar.gz" | cut -d : -f 2,3 | tr -d \"`
# get URLs and file names
first_file=`echo "$answer" | grep -Eo '.+?\.tar\.gz' | head -n1 | tr -d " "`
second_file=`echo "$answer" | grep -Eo '.+?\.tar\.gz' | head -n2 | tail -1 | tr -d " "`
first_file_name=`echo "$answer" | grep -Eo '[^/]+?\.tar\.gz' | head -n1 `
second_file_name=`echo "$answer" | grep -Eo '[^/]+?\.tar\.gz' | head -n2 | tail -1`
#echo $first_file
#echo $first_file_name
#echo $second_file_name
#echo $second_file
# download first file
wget "$first_file"
# extracting first one that must be in the current directory.
# else, change the directory first and put the path before $first_file!
tar -xzf "$first_file_name"
# do your stuff with the second file
You can simply pipe the URLs to xargs curl;
curl -s https://api.github.com/repos/mozilla-iot/gateway/releases/latest |
grep "browser_download_url.*tar.gz" |
cut -d : -f 2,3 | tr -d \" |
xargs curl -O
Or if you want to do some more manipulation on each URL, perhaps loop over the results:
curl ... | grep ... | cut ... | tr ... |
while IFS= read -r url; do
curl -O "$url"
: maybe do things with "$url" here
done
The latter could easily be extended to someting like
... | while IFS= read -r url; do
d=${url##*/}
mkdir -p "$d"
( cd "$d"
curl -O "$url"
tar zxf *.tar.gz
# end of subshell means effects of "cd" end
)
done

grep search with filename as parameter

I'm working on a shell script.
OUT=$1
here, the OUT variable is my filename.
I'm using grep search as follows:
l=`grep "$pattern " -A 15 $OUT | grep -w $i | awk '{print $8}'|tail -1 | tr '\n' ','`
The issue is that the filename parameter I must pass is test.log.However, I have the folder structure :
test.log
test.log.001
test.log.002
I would ideally like to pass the filename as test.log and would like it to search it in all log files.I know the usual way to do is by using test.log.* in command line, but I'm facing difficulty replicating the same in shell script.
My efforts:
var-$'.*'
l=`grep "$pattern " -A 15 $OUT$var | grep -w $i | awk '{print $8}'|tail -1 | tr '\n' ','`
However, I did not get the desired result.
Hopefully this will get you closer:
#!/bin/bash
for f in "${1}*"; do
grep "$pattern" -A15 "$f"
done | grep -w $i | awk 'END{print $8}'

Bash script any reason why it wont write the file

I am helping debug some code that exec the following script is there any reason why its not writing a file to the server? - if that what it does. All the $ data and permissions are ok:
Script:
#!/bin/bash
RANGE=$1
ALLOCATION=`echo $RANGE | cut -f1,2,3 -d'.'`
/sbin/ip rule add from $1 lookup $2
echo $ALLOCATION
rm /path/too/file/location/$ALLOCATION
for i in `seq 3 254`
do
echo $ALLOCATION.$i >> /path/too/file/location/$ALLOCATION
done
ETH=`/sbin/ifconfig | grep eth0 | tail -n1 | cut -f2 -d':' | cut -f1 -d' '`

Resources