shell script is not reading $HOME value properly - shell

I have tried to fetch the value from another file with below code snippet
file=`echo "$(read_properties 'abc.config')"` // reading this input from other file
abc.config =$HOME/one/two
$HOME = /home/cbc
but when i use line number 1, Actual = $HOME/one/two
Expected : /home/cbc/one/two
where if i only print $HOME it gives me output as /home/cbc
but why it is not printing properly when i use in file variable

Related

How to call a variable created in the script in Nextflow?

I have a nextflow script that creates a variable from a text file, and I need to pass the value of that variable to a command line order (which is a bioconda package). Those two processes happen inside the "script" part. I have tried to call the variable using the '$' symbol without any results, I think because using that symbol in the script part of a nextflow script is for calling variables defined in the input part.
To make myself clearer, here is a code sample of what I'm trying to achieve:
params.gz_file = '/path/to/file.gz'
params.fa_file = '/path/to/file.fa'
params.output_dir = '/path/to/outdir'
input_file = file(params.gz_file)
fasta_file = file(params.fa_file)
process foo {
//publishDir "${params.output_dir}", mode: 'copy',
input:
path file from input_file
path fasta from fasta_file
output:
file ("*.html")
script:
"""
echo 123 > number.txt
parameter=`cat number.txt`
create_report $file $fasta --flanking $parameter
"""
}
By doig this the error I recieve is:
Error executing process > 'foo'
Caused by:
Unknown variable 'parameter' -- Make sure it is not misspelt and defined somewhere in the script before using it
Is there any way to call the variable parameter inside the script without Nextflow interpreting it as an input file? Thanks in advance!
The documentation re the script block is useful here:
Since Nextflow uses the same Bash syntax for variable substitutions in
strings, you need to manage them carefully depending on if you want to
evaluate a variable in the Nextflow context - or - in the Bash
environment execution.
One solution is to escape your shell (Bash) variables by prefixing them with a back-slash (\) character, like in the following example:
process foo {
script:
"""
echo 123 > number.txt
parameter="\$(cat number.txt)"
echo "\${parameter}"
"""
}
Another solution is to instead use a shell block, where dollar ($) variables are managed by your shell (Bash interpreter), while exclamation mark (!) variables are handled by Nextflow. For example:
process bar {
echo true
input:
val greeting from 'Hello', 'Hola', 'Bonjour'
shell:
'''
echo 123 > number.txt
parameter="$(cat number.txt)"
echo "!{greeting} parameter ${parameter}"
'''
}
declare "parameter" in the top 'params' section.
params.parameter="1234"
(..)
script:
"""
(...)
create_report $file $fasta --flanking ${params.parameter}
(...)
"""
(...)
and call "nextflow run" with "--parameter 87678"

find and store a string after a pattern.It is hanging when sending path of file using a variable in sed ` `

disk/file1:
parameter wanted = 108,
From file1 I want to get value of wanted i.e 108 and store it in val. For this I used
val=`sed -n 's/.*wanted = \(.*\)\,.*/\1/p' disk/file1`
and it's working.
Now I want set this path to a variable and pass it same as above. But its not happening.
Code:
set pa=disk/file1
val=`sed -n 's/.*wanted = \(.*\)\,.*/\1/p' $pa`
How to pass $ values in ` `?
If you're using bash or similar, don't use set to assign values to variables (that was a (t)csh syntax). In fact, there's no keyword for it:
pa=disk/file1
What set does when it sees parameter it can't parse is it assigns it to the next positional parameter. For example,
set pa=disk/file1
sets $1 to pa=disk/file1. (Easily verifiable by echo "$1".)

How can I edit a .conf file easily?

So I read the easiest way to use .conf files for bash scripts is to use source to load such files. Now, what if I want to edit this file ?
Some code I found does a really good job :
function set_config(){
sed -i "s/^\($1\s*=\s*\).*\$/\1$2/" $conf_file
}
But, if the variable is not yet defined, it doesn't define it, nor does it check if the parameters are passed well, isn't secure, doesn't handle default values etc...
Does reliable tools/code already exists to edit .conf file which contain key="value" pairs ? For instance, I would like to be able to do things like this :
$conf_file="my_script.conf"
conf_load $conf_file #should create the file if it doesn't exist !
read=$(conf_get_value "data" "default_value") #should read the value with key "data", defaulting to "default_value"
if [[ $? = 0 ]] #we should be able to know if the read was successful
then
echo "Successfully read value for field \"data\" : $read"
else
echo "Default value for field \"data\" : $read"
fi
conf_set "something_new" "a great value!" #should add the key "something_new" as it doesn't exist
conf_set "data" "new_value" #should edit the value with key "data"
if [[ $? = 0 ]]
then
echo "Edit successful !"
else #something went wrong :-/
echo "Edit failed !"
fi
before running this code, the conf file would contain
data="some_value"
and after it would be
data="new_value"
something_new="a great value!"
and the code should output
Successfully read value for field "data" : some_value
Edit successful !
I am using bash version 4.3.30 .
Thanks for your help.
I'd to that with awk since it's rather good at tokenizing:
# overwrite config's entries for KEY with VALUE or else appends the definition
# Usage: set_config KEY VALUE
set_config() {
[ -n "$1" ] && awk -F= -v key="$1" -v new="$1=\"$2\"" '
$1 == key { $0 = new; key_found = 1; }
{ print }
END { if (!key_found) { print new; }
' "$conf_file" > "$conf_file.new" \
&& cat "$conf_file.new" > "$conf_file" && rm "$conf_file.new"
}
If run without arguments, set_config() will do nothing and return false. If run with only one argument, it will create an empty value (outputting KEY="").
The awk command parses the .conf file line by line, looking for each definition of the given key and altering it to the new value. All lines are then printed (with or without modification), preserving the original order. If the key hasn't yet been found by the end of the file, this appends the new definition.
Because you can't pipe a file atop itself, this gets saved with a ".new" extension and then copied atop the original in a manner that preserves permissions. The ".new" copy is then removed. I used && to ensure that these never happen if an error occurred earlier in the function.
Also note that the type of ".conf file" you're referring to (the type you source with a POSIX shell) will never have spaces around its equals signs, so the \s* parts of your sed command aren't needed.

Bash - How to read content of file into variable, the file was read from key->value property file?

I have one key->value property file (my.prop) with such a content:
ROOT_PATH = /opt/user1/
REL_PATH = data/folder1/
CONF_FILENAME = my.conf
In my bash script I simply read this file, like this:
#!/bin/bash
PROP_FILE='my.prop'
ROOT_PATH =''
REL_PATH=''
CONF_FILENAME=''
while read -r key eq value; do
case $key in
"ROOT_PATH")
ROOT_PATH=${value}
;;
case $key in
"REL_PATH")
REL_PATH=${value}
;;
case $key in
"CONF_FILENAME")
CONF_FILENAME=${value}
;;
esac
done < $PROP_FILE
After that I would like to form the path to my.conf file and read its content to some variable, like this:
CONF_FULL_PATH=$ROOT_PATH$REL_PATH$CONF_FILENAME
CONF_FILE_CONTENT=`cat ${CONF_FULL_PATH}`
If I print out CONF_FULL_PATH variable it will have some trash inside (parts of all three sub paths).
And at this lineCONF_FILE_CONTENT=`cat ${CONF_FULL_PATH}` I will have this error message - : No such file or directoryta/folder1/
So, my question is, how could I properly form the path to my.conf file and put its content to some specific variable? I already tried source command as a replacement for while loop. Also to build a proper path string I've used this statements:
$(dirname $ROOT_PATH)/$(dirname REL_PATH)/$(basename $CONF_FILENAME) but this looks odd for my point of view.
Any help would be great!
If you remove the spaces from your my.prop file, you can use source (or .) to read the variables inside it. This will make it much easier.
my.prop:
ROOT_PATH=/opt/user1/
REL_PATH=data/folder1/
CONF_FILENAME=my.conf
Then you can use these directly in your script:
#!/bin/bash
. my.prop
CONF_FULL_PATH="${ROOT_PATH}${REL_PATH}${CONF_FILENAME}"
CONF_FILE_CONTENT=$(cat "$CONF_FULL_PATH")

Calling external script in matlab and capturing output

Hey so I have a bash command that echos a string based on reading some file. Say for simplicity it is like this
for line in `cat file`
do
if [ "$line" == "IwantThisLine" ]
then
echo "True"
fi
done
And I have it saved as its own individual script. Its called readRef.sh. So now I want to call it in matlab and store whatever it outputs in a variable! I am not entirely sure on how to do that, I seem to get an error when using evalc() on a system(). But it could be just me messing up quotations.
I tried something like
evalc(system(['./readRef.sh ' bamfile']))
The "bamfile" is a variable that is just a string to the path of a bamfile.
I get this error.
>> tes = evalc(system(['./readRef.sh ' smplBamFile]))
hg18
??? Undefined function or method 'evalc' for input arguments of type 'double'.
Coincidentally it does spit out "hg18" which is what I want to set the matlab variable to be.
Oh, I see. I don't think you need evalc at all. Reading the system docs you can just do:
[status, result] = system('echo True; echo "I got a loverly bunch of coconuts"')
And result will be
True
I got a loverly bunch of coconuts
So just do:
[status, result] = system(['./readRef.sh ' smplBamFile])
The reason evalc isn't working is that it requires its input to be a Matlab expression in a string, but you are passing it the result of system.
You could try:
evalc("system(['./readRef.sh ' smplBamFile])")
See how I'm passing in the system(...) as a string?
The reason you get this error is because system(...) returns the return-code of the command it ran, not its output. To capture its output, use
[~, output] = system(...)
tes = evalc(output);

Resources