Why a new line character appending to shell variable? - ksh

I have used the method to assign the SQL output to a variable as below.
dbRole=$(${SQLPLUSPGM} -s / as sysdba <<-EOF
set head off
set verify off
set feedback off
select trim(translate(database_role,' ','_')) from v\$database;
exit;
EOF
)
But the variable o/p appending a "\n" character i.e \nPHYSICAL_STANDBY
However, when I use the below method it is working fine
${SQLPLUSPGM} -s / as sysdba <<-EOF | grep -v '^$' | read dbRole
set head off
set verify off
set feedback off
select trim(translate(database_role,' ','_')) from v\$database;
exit;
EOF
Any suggestion why it is appending `\n' and how we can get rid of it.
Appreciate your suggestions.

Your second method, with the grep -v, removes the additional line.
You can use some filter inside your first method with additional parentheses.
dbRole=$((cat | grep -v "^$") <<-EOF
1
2
3
5
EOF
)
Alternative filters with some differences are grep ., head -1, sed '$d'.

Related

Bash regex: get value in conf file preceded by string with dot

I have to get my db credentials from this configuration file:
# Database settings
Aisse.LocalHost=localhost
Aisse.LocalDataBase=mydb
Aisse.LocalPort=5432
Aisse.LocalUser=myuser
Aisse.LocalPasswd=mypwd
# My other app settings
Aisse.NumDir=../../data/Num
Aisse.NumMobil=3000
# Log settings
#Aisse.Trace_AppliTpv=blabla1.tra
#Aisse.Trace_AppliCmp=blabla2.tra
#Aisse.Trace_AppliClt=blabla3.tra
#Aisse.Trace_LocalDataBase=blabla4.tra
In particular, I want to get the value mydb from line
Aisse.LocalDataBase=mydb
So far, I have developed this
mydbname=$(echo "$my_conf_file.conf" | grep "LocalDataBase=" | sed "s/LocalDataBase=//g" )
that returns
mydb #Aisse.Trace_blabla4.tra
that would be ok if it did not return also the comment string.
Then I have also tryed
mydbname=$(echo "$my_conf_file.conf" | grep "Aisse.LocalDataBase=" | sed "s/LocalDataBase=//g" )
that retruns void string.
How can I get only the value that is preceded by the string "Aisse.LocalDataBase=" ?
Using sed
$ mydbname=$(sed -n 's/Aisse\.LocalDataBase=//p' input_file)
$ echo $mydbname
mydb
I'm afraid you're being incomplete:
You mention you want the line, containing "LocalDataBase", but you don't want the line in comment, let's start with that:
A line which contains "LocalDataBase":
grep "LocalDataBase" conf.conf.txt
A line which contains "LocalDataBase" but who does not start with a hash:
grep "LocalDataBase" conf.conf.txt | grep -v "^ *#"
??? grep -v "^ *#"
That means: don't show (-v) the lines, containing:
^ : the start of the line
* : a possible list of space characters
# : a hash character
Once you have your line, you need to work with it:
You only need the part behind the equality sign, so let's use that sign as a delimiter and show the second column:
cut -d '=' -f 2
All together:
grep "LocalDataBase" conf.conf.txt | grep -v "^ *#" | cut -d '=' -f 2
Are we there yet?
No, because it's possible that somebody has put some comment behind your entry, something like:
LocalDataBase=mydb #some information
In order to prevent that, you need to cut that comment too, which you can do in a similar way as before: this time you use the hash character as a delimiter and you show the first column:
grep "LocalDataBase" conf.conf.txt | grep -v "^ *#" | cut -d '=' -f 2 | cut -d '#' -f 1
Have fun.
You may use this sed:
mydbname=$(sed -n 's/^[^#][^=]*LocalDataBase=//p' file)
echo "$mydbname"
mydb
RegEx Details:
^: Start
[^#]: Matches any character other than #
[^=]*: Matches 0 or more of any character that is not =
LocalDataBase=: Matches text LocalDataBase=
You can use
mydbname=$(sed -n 's/^Aisse\.LocalDataBase=\(.*\)/\1/p' file)
If there can be leading whitespace you can add [[:blank:]]* after ^:
mydbname=$(sed -n 's/^[[:blank:]]*Aisse\.LocalDataBase=\(.*\)/\1/p' file)
See this online demo:
#!/bin/bash
s='# Database settings
Aisse.LocalHost=localhost
Aisse.LocalDataBase=mydb
Aisse.LocalPort=5432
Aisse.LocalUser=myuser
Aisse.LocalPasswd=mypwd
# My other app settings
Aisse.NumDir=../../data/Num
Aisse.NumMobil=3000
# Log settings
#Aisse.Trace_AppliTpv=blabla1.tra
#Aisse.Trace_AppliCmp=blabla2.tra
#Aisse.Trace_AppliClt=blabla3.tra
#Aisse.Trace_LocalDataBase=blabla4.tra'
sed -n 's/^Aisse\.LocalDataBase=\(.*\)/\1/p' <<< "$s"
Output:
mydb
Details:
-n - suppresses default line output in sed
^[[:blank:]]*Aisse\.LocalDataBase=\(.*\) - a regex that matches the start of a string (^), then zero or more whiespaces ([[:blank:]]*), then a Aisse.LocalDataBase= string, then captures the rest of the line into Group 1
\1 - replaces the whole match with the value of Group 1
p - prints the result of the successful substitution.

Update MariaDB table with variable from curl in bash script

I have read literally every answer on the net that I could find. Nothing is similar to my problem, so here it is:
I have a bash script with curl and I get a variable back. I want to update my database with this variable, however it doesn't work.
My variable is $stream and no matter what I do, I always get the word "$stream" into the database instead of the result of the curl.
My script is:
#!/bin/bash
stream=$(curl --silent "https://player.mediaklikk.hu/playernew/player.php?video=mtv1live&noflash=yes&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator=&osfamily=Windows&osversion=10&browsername=Chrome&browserversion=97.0.4692.99&title=M1&contentid=mtv1live&embedded=0" | grep -Po 'file": "\K(.*?)(?=")' | sed 's/\\\/\\\//https:\\\/\\\//g')
echo $stream
mysql
use mydatabase;
UPDATE my_table SET my_url = "$stream" WHERE my_name = 'stream_name';
You can use the -e option to execute a query. Put this in double quotes and variables will be expanded.
#!/bin/bash
stream=$(curl --silent "https://player.mediaklikk.hu/playernew/player.php?video=mtv1live&noflash=yes&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator=&osfamily=Windows&osversion=10&browsername=Chrome&browserversion=97.0.4692.99&title=M1&contentid=mtv1live&embedded=0" | grep -Po 'file": "\K(.*?)(?=")' | sed 's/\\\/\\\//https:\\\/\\\//g')
echo $stream
mysql mydatabase -e "UPDATE my_table SET my_url = '$stream' WHERE my_name = 'stream_name';"

Command Substitution does not execute unless i echo it

I have a method that curls, formats the output and returns it as an array.
function hdfs_ls_curl() {
ls_url=$1
ls_result=$(curl -s --negotiate -u : ${ls_url})
#gets the foldernames from the json returned. works fine.
folder_names=$(echo $ls_result | grep -oP '(?<="pathSuffix":").+?(?=")')
#echo $folder_names <--- MAGIC ECHO
folder_array=( $folder_names )
return $folder_array
}
If i execute without the echo, nothing is returned. Adding the echo lets it behave properly.
Is the command substitution not happening without an actual execution statement?
As GordonDavisson pointed out, removing the return statement and just printing it as an array did the job.
The function will return the printed value and i can parse that in the main program.
> folder_names=$(echo $ls_result | grep -oP '(?<="pathSuffix":").+?(?=")')
> #echo $folder_names <--- MAGIC ECHO
folder_names="echo $ls_result | grep -oP \'\(?<=\"pathSuffix\":\"\).+?\(?=\"\)\'"
eval $folder_names
That might work, but watch those escapes. This saves the actual command itself in the variable, rather than its' output.

Variable declaration with sed in cshell

I'm trying to parse a lattice with grep and save the output in a variable in a cshell script. But somehow I always get the error message "Illegal variable name" when adding the FILE_IN_B variable. I tried different spacings after the variables name and also tried $() ,or %.* ,instead of sed to remove the last four letters but neither works in cshell. Also tried setting the declaration in "", to no avail. I'm really desperate here...
#!/bin/csh
set FILE_IN = file.ext
set SOURCE = home/Developer
set FILE_IN_B=`sed '/.\{4\}$//' >>> "$FILE_IN"`.lat
set REC = `grep -C 1 'I=11' "$SOURCE/Lattice/$FILE_IN_B" | cut -d ' ' -f 3 | cut -d= -f 2| sed 's/sp//'`
csh has some built-in variable manipulation, including one meant for extension removal:
% set FILE_IN=file.ext
% set FILE_IN_B="${FILE_IN:r}.lat"
% echo "$FILE_IN_B"
file.lat
If sed is required then printf can be used as the standard input, similar to portable sh:
% set FILE_IN=file.ext
% set FILE_IN_B=`printf %s "$FILE_IN" | sed 's/.\{4\}$//'`.lat
% echo "$FILE_IN_B"
file.lat

Unix user created variables

I am going though some growing pains with Unix. My question:
I want to be able to print all my user defined variables in my shell. Let say I do the following in the shell:
$ x=9
$ y="Help"
$ z=-18
$ R="My 4th variable"
How would I go about printing:
x y z R
You should record your variables first at runtime with set, then compare it later to see which variables were added. Example:
#!/bin/bash
set | grep -E '^[^[:space:]]+=' | cut -f 1 -d = | sort > /tmp/previous.txt
a=1234
b=1234
set | grep -E '^[^[:space:]]+=' | cut -f 1 -d = | sort > /tmp/now.txt
comm -13 /tmp/previous.txt /tmp/now.txt
Output:
a
b
PIPESTATUS
Notice that there are still other variables produced by the shell but is not declared by the user. You can filter them with grep -v. It depends on the shell as well.
Add: Grep and cut could simply be just one sed a well: sed -n 's/^\([^[:space:]]\+\)=.*/\1/p'
Type set:
$ set
Apple_PubSub_Socket_Render=/tmp/launch-jiNTOC/Render
BASH=/bin/bash
BASH_ARGC=()
BASH_ARGV=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="3" [1]="2" [2]="51" [3]="1" [4]="release" [5]="x86_64-apple-darwin13")
BASH_VERSION='3.2.51(1)-release'
COCOS2DROOT=/Users/andy/Source/cocos2d
COLUMNS=80
DIRSTACK=()
...
(Oh, and BTW, you appear to have your variable syntax incorrect as you assign, say, A but print $A)
If variables are exported then you can use env command in Unix.

Resources