Shell Script do while flow - bash

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.

Related

Bash Script: Filter large files for value

I have several config files with around 20k lines each and I need to get some values from them.
I know that each of the values I need starts with a specific word "CONFNET" so I tried to get the values with a while loop, which reads every line.
But unfortunately this is extremely inefficient and slow.
Is there a better solution to this?
for filename in ~/configs/*; do
ip=$(cat $filename | strings | grep -i -A 7 "addnet_outside" | head -7 | grep "IP" | sed "s/IP//" | sed "s/=//" | sed -e 's/^[ \t]*//')
hostname=$(cat $filename | strings | grep -a "Inst:" | head -1 | sed "s/Inst://" | sed -e 's/^[ \t]*//')
while IFS= read -r line; do
object_name=$(echo $line | strings | grep "CONFNET" | sed "s/CONFNET//" | awk '{print $1}')
object_value=$(echo $line | strings | grep "CONFNET" | sed "s/CONFNET//" | awk '{print $3}' | sed -e 's/^[ \t]*//')
if [ ! -z $object_name ] && [ ! -z $object_value ]
then
echo $hostname "->" $object_name ":" $object_value
done < "$filename"
done

how to read words from a file using shell script

i have a file /ws/$1-rcd/temp.txt which has only one line as follows
198|/vob/ccm_tpl/repository/open_source/commons_collections/3_2_2/...
i have a script to get the value repository/open_source/commons_collections and 3_2_2 by reading the file and looping through it using for loop
i have my code as follows
grep -n "$4" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f1,2 | sed -e 's/\:element/|/g' | sed -e 's/ //g' > /ws/$1-rcd/temp.txt
for i in `cat /ws/$1-rcd/temp.txt`
do
line=`echo $i | cut -d"|" -f1`
path=`echo $i | cut -d"|" -f2`
whoami
directory_temp=`echo $path | awk -F "/" '{ print $(NF-2)}'`
if [ "$directory_temp" == "$4" ]
then
OLD_VERSION=`sed -n "${line}p" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f2 | awk -F "/" '{ print $(NF-1)}'`
total_fields=`sed -n "${line}p" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f2 | awk -F "/" '{ print NF }'`
dir_path=`expr ${total_fields} - 2`
loc=`sed -n "${line}p" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f2 | cut -d"/" -f1-"${dir_path}"`
location=`echo $loc | cut -d"/" -f4,5,6`
fi
done
but when i run this code it gives me an error as
-bash: line 45: syntax error near unexpected token |'
-bash: line 45:for i in 198|/vob/ccm_tpl/repository/open_source/commons_collections/3_2_2/...'
can anyone please suggest what am i doing wrong
If you want to iterate through each line of a file, use while loop like below
while read -r line ;do
echo $line
done <file.txt
so, your code can be rewritten as
grep -n "$4" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f1,2 | sed -e 's/\:element/|/g' | sed -e 's/ //g' > /ws/$1-rcd/temp.txt
while read i ; do
line=`echo $i | cut -d"|" -f1`
path=`echo $i | cut -d"|" -f2`
whoami
directory_temp=`echo $path | awk -F "/" '{ print $(NF-2)}'`
if [ "$directory_temp" == "$4" ]
then
OLD_VERSION=`sed -n "${line}p" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f2 | awk -F "/" '{ print $(NF-1)}'`
total_fields=`sed -n "${line}p" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f2 | awk -F "/" '{ print NF }'`
dir_path=`expr ${total_fields} - 2`
loc=`sed -n "${line}p" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f2 | cut -d"/" -f1-"${dir_path}"`
location=`echo $loc | cut -d"/" -f4,5,6`
fi
done < /ws/$1-rcd/temp.txt
You may be better served relying on parameter expansion and substring removal. For example:
#!/bin/sh
a=$(<dat/lline.txt) ## read file into a
a=${a##*ccm_tpl/} ## remove from left to ccm_tpl/
num=${a##*collections/} ## remove from left to collections/
num=${num%%/*} ## remove from right to /
a=${a%%${num}*} ## remove from right to $num
Input File
$ cat dat/lline.txt
198|/vob/ccm_tpl/repository/open_source/commons_collections/3_2_2/..
Output
$ sh getvals.sh
a : repository/open_source/commons_collections/
num : 3_2_2
If you need to trim in some other way, just let me know and I'm happy to help further.

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' '`

Using bash command on a variable that will be used as reference for an array

Short and direct, basically I want to use the value of $command on a variable, instead using it inside the while loop as a command itself. So:
This Works, but I think it's ugly:
#!/bin/bash
IFS=$'\n'
lsof=`which lsof`
whoami=`whoami`
while true ; do
execution_array=($(${lsof} -iTCP -P 2> /dev/null | grep ':' | grep ${whoami} | awk '{print $9}' | cut -f2 -d'>' | sort | uniq ))
for i in ${execution_array[*]}; do
echo $i
done
sleep 1
done
unset IFS
This doesn't work ( no output happens ), but i think is less ugly:
#!/bin/bash
IFS=$'\n'
lsof=`which lsof`
whoami=`whoami`
command="${lsof} -iTCP -P 2> /dev/null | grep ':' | grep ${whoami} | awk '{print $9}' | cut -f2 -d'>' | sort | uniq"
while true ; do
execution_array=($(command))
for i in ${execution_array[*]}; do
echo $i
done
sleep 1
done
unset IFS
This solved my problem:
#!/bin/bash
IFS=$'\n'
lsof=$(which lsof)
list_connections() {
${lsof} -iTCP -P 2> /dev/null | grep ':' | grep $(whoami) | awk '{print $9}' | cut -f2 -d'>' | sort | uniq
}
while true ; do
execution_array=($(list_connections))
for i in ${execution_array[*]}; do
echo $i
done
sleep 1
done
unset IFS

OpenStreetMap Bash / CGI Script

I am trying to build a Bash CGI Script that takes in coordinates as parameters from the url and uses osmosis to extract the map and the splitter and mkgmap to make the map so that it can be opened with Qlandkarte. My problem being is that when i type wget localhost/cgi-bin/script.pl?top=42&left=10&bottom=39&right=9&file=map.osm the linux terminal reads the file with the coordinates. How can I make wget just activate the script so it takes the coordinates and executes the commands. And also when the map is created at the end how can a return the file that was created by the script.
Thanks
#!/bin/bash
TOP=`echo "$QUERY_STRING" | grep -oE "(^|[?&])top=[0.0-9.0]+" | cut -f 2 -d "=" | head -n1`
LEFT=`echo "$QUERY_STRING" | grep -oE "(^|[?&])left=[0.0-9.0]+" | cut -f 2 -d "=" | head -n1`
BOTTOM=`echo "$QUERY_STRING" | grep -oE "(^|[?&])bottom=[0.0-9.0]+" | cut -f 2 -d "=" | head -n1`
RIGHT=`echo "$QUERY_STRING" | grep -oE "(^|[?&])right=[0.0-9.0]+" | cut -f 2 -d "=" | head -n1`
FILE=`echo "$QUERY_STRING" | grep -oE "(^|[?&])file=[^&]+" | sed "s/%20/ /g" | cut -f 2 -d "="`
$(sudo osmosis --read-xml file=bulgaria.osm --bounding-box top=$TOP left=$LEFT bottom=$BOTTOM right=$RIGHT --write-xml file=$FILE)
$(sudo java -Xmx900m -jar splitter.jar --max-nodes=110000 $FILE)
$(sudo java -ea -Xmx900m -jar mkgmap.jar --tdbfile --route -c template.args)
echo "Content-type: text/html"
echo ""

Resources