Using Bash parameter expansion with Required check - bash

I am trying to strip the string value in the variable and copy to another variable using bash parameter expansion.
initialModified=${initial#abc}
This give me the value in initialModified after stripping out abc from the beginning of the string in initial variable when I echo initialModified.
However, along with this I would like to add required check
initialModified=${initial#abc:?Required parameter}
This doesn't work as expected. And throws an error.
Any help is appreciated.

Related

How to remove initial dot from a string in a variable in bash

I have a variable named myVar in bash with value as shown below.
'./favicon.png' './inc/sendEmail.php' './index.html' './images/header-background.jpg'
Note: the above code is the value of one variable
And I want want to change it to the below string by removing initial dot from each path
'/favicon.png' '/inc/sendEmail.php' '/index.html' '/images/header-background.jpg'
I am not able to figure out how to do this. Please help.
With a bash parameter expansion?
#!/bin/bash
myVar="'./favicon.png' './inc/sendEmail.php' './index.html' './images/header-background.jpg'"
echo "${myVar//.\///}"
'/favicon.png' '/inc/sendEmail.php' '/index.html' '/images/header-background.jpg'

Braces in shell parameter expansion don't work right

I have a program parsing two files and comparing them looking for conflicts between the two and allowing the user to decide what action to take. As a result, I need to be able to parse the lines below. If a string contains { or } when using pattern replacement parameter expansion it will cause an error.
I was looking for a potential work around for the following lines
F=TSM_CLASS="Test text {class}"
newstring=${F//{class}/\\{class\\}}
Results:
echo $newstring
TSM_CLASS="Test text }/\{class\}}"
${F//{class} is a complete parameter expansion which replaces every instance of {class in F's value with empty string. To embed braces in the pattern and/or the replacement string, you need to quote them.
$ F=TSM_CLASS="Test text {class}"
$
$ echo "${F//{class\}/\\{class\\\}}"
TSM_CLASS=Test text \{class\}

Call variable from within variable

I have a source file which contains several libraries for names of variables. For example:
qvs_var1="ABC1"
qvs_var2="LMN2"
qvs_var3="LNE5"
qvs_var4="RST2"
....
Loading in the source file at the beginning of another file with:
source lib_file.csh
I now have access to the variables listed above. I want to access them dynamically and sequentially from a file prompting the variables to process. For example:
# Load in source file
source lib_file.csh
# Read in variables to process
vars=$(<variables_to_process.txt)
# For this example, vars = var1 var3
# Begin looping
For var in ${vars}
do
echo ${qvs_${var}}
done
Where the output should be: ABC1, and then LNE5. The error in the echo line above prompts: 'bad substitution'. What is the proper format to achieve what is needed?
What you are after is called indirection:
${parameter} The value of parameter is substituted. The braces are required when parameter is a positional parameter with more than one digit, or when parameter is followed by a character which is not to be interpreted as a part of its name.
If the first character of parameter is an exclamation point (!), a level of variable indirection is introduced. Bash uses the value of the variable formed from the rest of the parameter as the name of
the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of parameter itself. This is known as indirect expansion. The exceptions to this are the expansions of ${!prefix*} and ${!name[#]} described below. The exclamation point must immediately follow the left brace in order to introduce indirection.
source: man bash
Below you find a simple example:
$ foo_1="car"
$ bar="1"
We are now interested in printing the value of foo_1 using bar:
$ tmpvar="foo_$bar"
$ echo ${!tmpvar}
car

how to keep nested BASH parameter untokenized

Consider this trite BASH script:
g1="f 2.txt"
g2="f1.txt $g1"
cp $g2
It fails because I passed three parameters to the cp command. How do I escape the $g1 call to make it pass just two on the final line (er, make it work without passing two variables on line three)? I tried putting quotes around it with no success; it then proceeds to pass the quotes as part of the parameter, which is doubly weird.
In my real scenario I have some optional parameters that themselves take parameters. I had wanted to parse them all out at the top of the script and leave their final parsed values blank if they weren't passed in.
You can do it using shell arrays:
g1="f 2.txt"
g2=("f1.txt" "$g1")
cp "${g2[#]}"

Bash variable character replacement ends up to an empty string or a command not valid

I am working on a shell script to retrieve variable content from a JSON file via JQ. The JSON file is in string format (no matter whether this is a real string or a number) and to retrieve the variable in my bash script I did something like this
my_domain=$(cat /vagrant/data_bags/config.json | jq ."app"[0]."domain")
The above code once echoed results in "mydomain" with a beginning and a trailing quote sign. I though this was a normal behaviour of the echo command. However, while concatenating my variable with another shell command the system raise an error. For instance, the following command
cp /vagrant/public_html/index.php "/var/www/"+$my_domain+"/index.php"
fails with the following error
cp: cannot create regular file `/var/www/+"mydomain"+/index.php': No such file or directory
At this stage, I wasn't able to identify whether it's me doing the wrong concatenation with the plus sign or the variable is effectively including the quotes that in any case will end up generating an error.
I have tried to replace the quotes in my variable, but I ended up getting the system raising a "Command not found" error.
Can somebody suggest what am I doing wrong?
+ is not used for string concatenation in bash (or perl, or php). Just:
cp /vagrant/public_html/index.php "/var/www/$my_domain/index.php"
Embedding a variable inside a double-quoted text string is known as interpolation, and is one of the reasons why we need the $ prefix, to indicate that this is a variable. Interpolation is specifically not done inside single quoted strings.
Braces ${my_domain} are not required because the / directory separators are not valid characters in a variable name, so there is no ambiguity.
For example:
var='thing'
echo "Give me your ${var}s" # Correct, appends an 's' after 'thing'
echo "Give me your $vars" # incorrect, looks for a variable called vars.
If a variable (like 'vars') does not exist then (by default) it will not complain, it will just give an empty string. Braces (graph brackets) are required more in c-shell (csh or tcsh) because of additional syntax for modifying variables, which involves special trailing characters.
You don't need to use + to concatenate string in bash, change your command to
cp /vagrant/public_html/index.php "/var/www/"${my_domain}"/index.php"
My problem was not related only to the wrong concatenation, but also to the JQ library that after parsing the value from the JSon file was returning text between quotes.
In order to avoid JQ doing this, just add the -rawoutput parameter when calling JQ.

Resources