I'm writing a script to send SQL output in mail, but it is not executing successfully and is not generating the output I want.
The query generates two columns with multiple rows. How can I generate the output in table format as below?
Below is my code:
#!/bin/bash
ORACLE_HOME= **PATH
export ORACLE_HOME
PATH=$PATH:$ORACLE_HOME/bin
export PATH
TNS_ADMIN= ** PATH
export TNS_ADMIN
today=$(date +%d-%m-%Y)
output=$(sqlplus -S user/pass#service <<EOF
set heading off;
SELECT distinct list_name ,max(captured_dttm) as Last_received FROM db.table1
group by list_name having max(captured_dttm) <= trunc(sysdate - interval '2' hour);
EOF)
if [ -z "$output" ];
then
echo"its fine"
exit
else
echo "
Dear All,
Kindly check we've not received the list for last 2 hour : $output
Regards,
Team" | mailx -S smtp=XX.XX.X.XX:XX -s "URGENT! Please check list FOR $today" user#abc.com
fi
When using a here document, the closing string can't be followed by anything but a newline. Move the closing parenthesis to the next line:
output=$(sqlplus -S user/pass#service <<EOF
...
EOF
)
My shell script executes a SQL to fetch the data in the following format:
JOB_ID_001|[PROD] This is a mail subject one ${application_date}|a#example.com,b#example.com
JOB_ID_002|[PROD] This is a mail subject two ${application_date}|c#example.com,b#example.com
I want to split this pipe-separated string, but the output looks very odd as follows:
JOB_ID_001[0]
JOB_ID_001[1]
JOB_ID_001[2]
This[0]
This[1]
This[2]
is[0]
is[1]
is[2]
a[0]
a[1]
a[2]
mail[0]
mail[1]
mail[2]
subject[0]
subject[1]
subject[2]
one[0]
one[1]
one[2]
${application_date}[0]
${application_date}[1]
${application_date}[2]
example.com,b#example.com[0]
example.com,b#example.com[1]
example.com,b#example.com[2]
JOB_ID_002[0]
JOB_ID_002[1]
JOB_ID_002[2]
This[0]
This[1]
This[2]
is[0]
is[1]
is[2]
a[0]
a[1]
a[2]
mail[0]
mail[1]
mail[2]
subject[0]
subject[1]
subject[2]
two[0]
two[1]
two[2]
${application_date}[0]
${application_date}[1]
${application_date}[2]
ple.com,b#example.com[0]
ple.com,b#example.com[1]
ple.com,b#example.com[2]
My desired output is:
JOB_ID_001
[PROD] This is a mail subject one ${application_date}
a#example.com,b#example.com
JOB_ID_002
[PROD] This is a mail subject two ${application_date}
c#example.com,b#example.com
So that I can continue with those strings.
My shell script is as follows:
email_configs=(`sqlplus -silent $DB_CONN <<-EOF
whenever sqlerror exit 1 oserror exit oscode
set heading off feedback off echo off verify off pagesize 0
$sql_subject_of_mail;
exit;
EOF`)
for i in "${!email_configs[#]}"
do
email_config=${email_configs[i]}
IFS='|' read -r -a email_config_array <<< "$email_config"
job_id=$email_config_array[0]
subject_of_mail=$email_config_array[1]
to_mail_id=$email_config_array[2]
echo $job_id
echo $subject_of_mail
echo $to_mail_id
done
I checked some alternate solutions from this page, but in the output ${application_date} part is missing or there is some other problem.
Can anyone have an idea about my mistake?
The $email_configs array is not being set correctly. It's using spaces as the array delimiters, not newlines.
Rather than set an array, read the output of sqlplus in a loop.
while IFS='|' read -r job_id subject_of_mail to_mail_id
do
echo "$job_id"
echo "$subject_of_mail"
echo "$to_mail_id"
done < <(sqlplus -silent $DB_CONN <<-EOF
whenever sqlerror exit 1 oserror exit oscode
set heading off feedback off echo off verify off pagesize 0
$sql_subject_of_mail;
exit;
EOF
)
I am working on a bash script and I got a list of IP's that I wanted to add one by one in a CURL command.
For example given list on a file named list.txt
8.8.8.8
10.10.10.10
136.34.24.22
192.168.10.32
I wanted to add each value on curl command
curl -k -u $user:$password "https://logservice/jobs" --data-urlencode 'search=search index=test $ARRAYVALUE | head 1' > output.txt
Where $ARRAYVALUE is the IP address to be used on the command.
I will appreciate any hint.
Thanks
If I understood correctly, you want to:
map each line of a "list.txt" to an item of an array
loop over the newly created array inserting items one by one into your command invocation
Consider this, heavily commented, snippet. Look especially at mapfile and how variable is used in curl invocation, surrounded by double quotes.
#!/bin/bash
# declare a (non-associative) array
# each item is indexed numerically, starting from 0
declare -a ips
#put proper values here
user="userName"
password="password"
# put file into array, one line per array item
mapfile -t ips < list.txt
# counter used to access items with given index in an array
ii=0
# ${#ips[#]} returns array length
# -lt makes "less than" check
# while loops as long as condition is true
while [ ${ii} -lt ${#ips[#]} ] ; do
# ${ips[$ii]} accesses array item with the given (${ii}) index
# be sure to use __double__ quotes around variable, otherwise it will not be expanded (value will not be inserted) but treated as a string
curl -k -u $user:$password "https://logservice/jobs" --data-urlencode "search=search index=test ${ips[$ii]} | head -1" > output.txt
# increase counter to avoid infinite loop
# and access the next item in an array
((ii++))
done
You may read about mapfile in GNU Bash reference: Built-ins.
You may read about creating and accessing arrays in GNU Bash reference: Arrays
Check this great post about quotes in bash.
I hope you found this answer helpful.
I believe you need something like this :
#!/bin/bash
function FN()
{
filename=$1
declare -a IPs_ARRAY
i=0
user=$2
password=$3
while read ip
do
IPs_ARRAY[$i]=$ip
echo ${IPs_ARRAY[$i]}
# Uncomment for your actions ::
#curl -k -u $user:$password "https://logservice/jobs" --data-urlencode 'search=search index=test ${IPs_ARRAY[$i]} | head 1' > output.txt
(( i++ ))
done < $filename
}
#############
### MAIN ###
###########
read -p "Enter username: " username
read -p "Enter password: " password
# Call your function
filename="list.txt"
FN $filename $username $password
Below is my requirement. I have a text file that has following content
File name - abc.txt
Content -
apple=0
mango=1
strawberry=10
I need to kick off the subsequent process only if any of the above stated variable has non zero values.
In this case, As two variables have values 1 and 10 respectively, I need to update an indicator - SKIP INDICATOR=N
If all variables have 0 as value, I need to update SKIP INDICATOR=Y
How to achieve this functionality in Linux. Kindly advise.
with very simple greps :
if [ $(grep '=' your_file | grep -v '=0') ]
then
echo "non zero values detected"
SKIP_INDICATOR=N
else
echo "all are zeroes"
SKIP_INDICATOR=Y
fi
Just note that this is a quick and dirty solution and it would NOT work properly if you have for example a=01 or a= 0 (eg with space)
Try:
grep -q '=0*[1-9]' textfile && skip_indicator=N || skip_indicator=Y
=0*[1-9] matches an '=' character followed by zero or more '0' characters followed by a digit in the range 1 to 9.
See Correct Bash and shell script variable capitalization for an explanation of why I changed SKIP_INDICATOR to skip_indicator.
#!/bin/bash
flag=`awk -F'=' '$NF!="0"{print;exit}' input`
if [ ! -z $flag ] ; then
SKIP_INDICATOR=N
echo "some variable value is different from 0. do something"
else
SKIP_INDICATOR=Y
echo "all variables have 0 as value. do another thing."
fi
exit 0
Need to extract the below query data along with header in csv file using shell script.
Below is the query.
SELECT SourceIdentifier,SourceFileName,ProfitCentre2,PlantCode,
tax_retur ReturnPeriod,document_number DocumentNumber,TO_CHAR(invoice_generation_date,'YYYY-MM-DD')
Docume,Original,customer_name CustomerName,NVL(sns_pos,new_state_code)POS,PortCode,NEW_HSN_CODE HSNorSAC,(SGSATE+UTGSATE) Stat,(SGS+UT)StateUT,Userde FROM arbor.INV_REPO_FINA WHERE UPPER(document_type)='INV' AND UPPER(backout_flag)='VALID' AND new_gst_id_new IS NOT NULL AND new_charges<>0 AND taxable_adj=0
UNION
SELECT SourceIdentifier,SourceFileName,ProfitCentre2,PlantCode,
tax_retur ReturnPeriod,document_number DocumentNumber,TO_CHAR(invoice_generation_date,'YYYY-MM-DD')
Docume,Original,customer_name CustomerName,NVL(sns_pos,new_state_code)POS,PortCode, NEW_HSN_CODE HSNorSAC,(SGSATE+UTGSATE) Stat,(SGS+UTG)StateUT,Userde FROM arbor.INV_REPO_FINA WHERE UPPER(document_type)='INV' AND UPPER(backout_flag)='VALID' AND new_gst_id_new IS NOT NULL AND new_charges<>0 AND taxable_adj<>0
Could please let me know if below approach to fetch data using shell script is correct and script is correct.
#!/bin/bash
file="output.csv"
sqlplus -s username/password#Oracle_SID << EOF
SPOOL $file
select 'SourceIdentifier','SourceFileName','ProfitCentre2','PlantCode',
'tax_retur ReturnPeriod','document_number DocumentNumber','TO_CHAR(invoice_generation_date,'YYYY-MM-DD') Docume','Original','customer_name CustomerName','NVL(sns_pos,new_state_code)POS','PortCode','NEW_HSN_CODE HSNorSAC','(SGSATE+UTGSATE) Stat','(SGS+UT)StateUT','Userde' from dual
Union all
select 'TO_CHAR(SourceIdentifier)','TO_CHAR(SourceFileName)','TO_CHAR(ProfitCentre2)','TO_CHAR(PlantCode)',
'TO_CHAR(tax_retur ReturnPeriod)','TO_CHAR(document_number DocumentNumber)','TO_CHAR(invoice_generation_date,'YYYY-MM-DD')
Docume','TO_CHAR(Original)','TO_CHAR(customer_name CustomerName)','TO_CHAR(NVL(sns_pos,new_state_code)POS)','TO_CHAR(PortCode)','TO_CHAR(NEW_HSN_CODE HSNorSAC)','TO_CHAR((SGSATE+UTGSATE) Stat)','TO_CHAR((SGS+UT)StateUT)','TO_CHAR(Userde)' from
(SELECT SourceIdentifier,SourceFileName,ProfitCentre2,PlantCode,
tax_retur ReturnPeriod,document_number DocumentNumber,TO_CHAR(invoice_generation_date,'YYYY-MM-DD')
Docume,Original,customer_name CustomerName,NVL(sns_pos,new_state_code)POS,PortCode,NEW_HSN_CODE HSNorSAC,(SGSATE+UTGSATE) Stat,(SGS+UT)StateUT,Userde FROM arbor.INV_REPO_FINA WHERE UPPER(document_type)='INV' AND UPPER(backout_flag)='VALID' AND new_gst_id_new IS NOT NULL AND new_charges<>0 AND taxable_adj=0
UNION
SELECT SourceIdentifier,SourceFileName,ProfitCentre2,PlantCode,
tax_retur ReturnPeriod,document_number DocumentNumber,TO_CHAR(invoice_generation_date,'YYYY-MM-DD')
Docume,Original,customer_name CustomerName,NVL(sns_pos,new_state_code)POS,PortCode, NEW_HSN_CODE HSNorSAC,(SGSATE+UTGSATE) Stat,(SGS+UTG)StateUT,Userde FROM arbor.INV_REPO_FINA WHERE UPPER(document_type)='INV' AND UPPER(backout_flag)='VALID' AND new_gst_id_new IS NOT NULL AND new_charges<>0 AND taxable_adj<>0)
SPOOL OFF
EXIT
EOF
In short: the ; is missing from the end of the select statement.
Some unrequested advice:
I think spool will put extra stuff into your file (at least some new lines), a redirect is better, further the first line is not db-related:
echo "SourceIdentifier;SourceFileName;ProfitCentre2..." > $file
I recommend to generate the csv format right in the select query, later it will be more headache (you can escape there what you want):
$query = "select SourceIdentifier || ';' || SourceFileName || ';' || ProfitCentre2 ... ;"
So querying the DB (I think capital -S is the right one) plus for the formatting of the records (and maybe you want to format your columns too):
sqlplus -S username/password#Oracle_SID >> $file << EOF
set linesize 32767 pagesize 0 heading off
$query
EOF
For me this one is working but one empty line before first query and second query is coming. Empty line remove using awk command
#!/bin/bash
FILE="A.csv"
$ORACLE_HOME/bin/sqlplus -s username/password#Oracle_SID<<EOF
SET PAGESIZE 50000 COLSEP "," LINESIZE 20000 FEEDBACK OFF HEADING off
SPOOL $FILE
select 'TYPE_OF_CALL_V','SWITCH_CALL_TYPE_V','RECORD_TYPE_V','TARF_TYPE_V' from dual;
SELECT TYPE_OF_CALL_V,SWITCH_CALL_TYPE_V,RECORD_TYPE_V,TARF_TYPE_V FROM TABLE;
SPOOL OFF
EXIT
EOF
awk 'NF > 0' $FILE > out.txt
mv out.txt $FILE