Variable getting expanded which is used inside another command? - shell

I am new to shell scripting .I am stuck with a very basic issue .I have a variable which I want to use with awk command to extract certain values .sample eg is below
sbt_value="1.0.1 analy 2.12.12"
#I want to extract each values out of this variable to three separate variable
version= $(echo $sbt_value |awk -F ' ' '{print $1}')
imagename= $(echo $sbt_value |awk -F ' ' '{print $2}')
scala_version= $(echo $sbt_value |awk -F ' ' '{print $3}')
I did as above but the issue I am facing is sbt_value variable get expanded on executing above script and I got error ../databricks_deploy/test.sh: line 9: 1.0.1: command not found.
Any help on this will be appreciated

Use the read command.
read version imagename scala_version <<< "$sbt_value"
If you are using a stricter POSIX-compliant shell that doesn't support here strings (the <<< syntax), you can use a here document:
read version imagename scala_version <<EOF
$sbt_version
EOF

Related

give a file without changing the name in script [duplicate]

This question already has answers here:
How to pass parameters to a Bash script?
(4 answers)
Closed 1 year ago.
At the beginning I have a file.txt, which contains several informations that I will take using the grep command as you see in the script.
What I want is to give the script the file I want instead of file.txt but without changing the file name each time in the script for example if the file is named Me.txt I don’t want to go into the script and write Me.txt in each grep command especially if I have dozens of orders.
Is there a way to do this?
#!/bin/bash
grep teste file.txt > testline.txt
awk '{print $2}' testline.txt > test.txt
echo '#'
echo '#'
grep remote file.txt > remoteline.txt
awk '{print $3}' remoteline.txt > remote.txt
echo '#'
echo '#'
grep adresse file.txt > adresseline.txt
awk '{print $2}' adresseline.txt > adresse.txt
Using a parameter, as many contributors here suggested, is of course the obvious approach, and the one which is usually taken in such case, so I want to extend this idea:
If you do it naively as
filename=$1
you have to supply the name on every invocation. You can improve on this by providing a default value for the case the parameter is missing:
filename=${1:-file.txt}
But sometimes you are in a situation, where for some time (working on a specific task), you always need the same filename over and over, and the default value happens to be not the one you need. Another possibility to pass information to a program is via the environment. If you set the filename by
filename=${MOOFOO:-file.txt}
it means that - assuming your script is called myscript.sh - if you invoke your script by
MOOFOO=myfile.txt myscript.sh
it uses myfile.txt, while if you call it by
myscript.sh
it uses the default file.txt. You can also set MOOFOO in your shell, as
export MOOFOO=myfile.txt
and then, even a lone execution of
myscript.sh
with use myfile.txt instead of the default file.txt
The most flexible approach is to combine both, and this is what I often do in such a situation. If you do in your script a
filename=${1:-${MOOFOO:-file.txt}}
it takes the name from the 1st parameter, but if there is no parameter, takes it from the variable MOOFOO, and if this variable is also undefined, uses file.txt as the last fallback.
You should pass the filename as a command line parameter so that you can call your script like so:
script <filename>
Inside the script, you can access the command line parameters in the variables $1, $2,.... The variable $# contains the number of command line parameters passed to the script, and the variable $0 contains the path of the script itself.
As with all variables, you can choose to put the variable name in curly brackets which has advantages sometimes: ${1}, ${2}, ...
#!/bin/bash
if [ $# = 1 ]; then
filename=${1}
else
echo "USAGE: $(basename ${0}) <filename>"
exit 1
fi
grep teste "${filename}" > testline.txt
awk '{print $2}' testline.txt > test.txt
echo '#'
echo '#'
grep remote "${filename}" > remoteline.txt
awk '{print $3}' remoteline.txt > remote.txt
echo '#'
echo '#'
grep adresse "${filename}" > adresseline.txt
awk '{print $2}' adresseline.txt > adresse.txt
By the way, you don't need two different files to achieve what you want, you can just pipe the output of grep straight into awk, e.g.:
grep teste "${filename}" | awk '{print $2}' > test.txt
but then again, awk can do the regex match itself, reducing it all to just one command:
awk '/teste/ {print $2}' "${filename}" > test.txt

Extract nth column from a variable

i have a variable Firstline with value FHEAD,0000000001,STKU,20150927000000,201509270000000000,1153,,0000000801,W from which i need 5th field alone.
Can any one help me to resolve this.
I have used the below command but it is giving me an error
echo "FHEAD,0000000001,STKU,20150927000000,201509270000000000,1153,,0000000801,W" | awk -f ',' '{print $5}'
awk: fatal: can't open source file
,' for reading (No such file or directory)
As you tag it as bash and not awk (which is also a valid solution), you can do
IFS=, read -a a <<< "FHEAD,0000000001,STKU,20150927000000,201509270000000000,1153,,0000000801,W"
echo ${a[4]}
to obtain the same result without spawning a new process (note that bash arrays are 0-based).
Try -F not -f.
-F is for the field separator
-f is for the filename of the awk program.
You can use sed too
echo "..." | sed -E 's/([^,]*,){4}([^,]*).*/\2/'

Trying to get awk o/p assigned to variable inside shell script

Need help with awk
Trying to get awk o/p assigned to variable; getting following error.
var= $(awk '{print $2;next;}' <<< "$OLD_ADDR")
echo $var
Where ...OLD_ADDR = "gateway 192.168.1.1"
******** Error from console log using set -x *******
+++ awk '{print $2;next;}'
++ var=
++ 192.168.1.21
-bash: 192.168.1.21: command not found
++ echo
Thank you,
pisignage#ariemtech.com
Spaces matter.
Consider:
var= $(awk '{print $2;next;}' <<< "$OLD_ADDR")
This tells the shell to set the variable var to empty and then run whatever command the awk statement prints out. In your case, that command is 192.168.1.1. Since the shell can find no such command on the PATH, the error is generated:
-bash: 192.168.1.21: command not found
The solution is to write:
var=$(awk '{print $2;next;}' <<< "$OLD_ADDR")
This will, by contrast, assign the output of the awk command to var.
When making an assignment in shell, no spaces are allowed on either side of the equal sign.

BASH - add prefix (file path) to each line in text file using awk

I am trying to get the full path of a files within a directory. So far this is what I have in bash.
prefix="s3://${s3_bucket}/${s3_folder}/$(date --date="$i days ago" +"%Y/%m/%d")/"
#echo $prefix
aws s3 ls s3://${s3_bucket}/${s3_folder}/$(date --date="$i days ago" +"%Y/%m/%d")/ | sed -n 's/.*\([0-9][0-9]-h.*gz\)/\1/p' | awk '$0="${prefix}"$0' >> ${s3_files_1}
In my output, I am getting the following:
${prefix}file1.gz
${prefix}file2.gz
The output I am looking for is something like below.
s3://my_bucket/my_folder/file1.gz
s3://my_bucket/my_folder/file2.gz
My issue is with the way the awk command is interpreting the variable ${prefix}. Can anyone please help?
You can use -v to pass shell variable contents to awk:
prefix="s3://my_bucket/my_folder/"
echo "file1.gz" | awk -v myprefix="${prefix//\\/\\\\}" '{ print myprefix $0 }'
Sadly, awk -v is not data safe. This example uses parameter expansion to escape backslashes to avoid them being mangled.

Shell scripting and using backslashes with back-ticks?

I'm trying to do some manipulation with Wordpress and I'm trying to write a script for it...
# cat /usr/local/uftwf/_wr.sh
#!/bin/sh
# $Id$
#
table_prefix=`grep ^\$table_prefix wp-config.php | awk -F\' '{print $2}'`
echo $table_prefix
#
Yet I'm getting following output
# /usr/local/uftwf/_wr.sh
ABSPATH ABSPATH wp-settings.php_KEY LOGGED_IN_KEY NONCE_KEY AUTH_SALT SECURE_AUTH_SALT LOGGED_IN_SALT NONCE_SALT wp_0zw2h5_ de_DE WPLANG WP_DEBUG s all, stop editing! Happy blogging. */
#
Running from command line, I get the correct output that I'm looking for:
# grep ^\$table_prefix wp-config.php | awk -F\' '{print $2}'
wp_0zw2h5_
#
What is going wrong in the script?
The problem is the grep command:
table_prefix=`grep ^\$table_prefix wp-config.php | awk -F\' '{print $2}'`
It either needs three backslashes - not one - or you need to use single quotes (which is much simpler):
table_prefix=$(grep '^$table_prefix' wp-config.php | awk -F"'" '{print $2}')
It's also worth using the $( ... ) notation in general.
The trouble is that the backquotes removes the backslash, so the shell variable is evaluated, and what's passed to grep is, most likely, just ^, and each line starts with a beginning of line.
This has all the appearance as though the grep is not omitting all the lines that are not matching, when you issue the echo $table_prefix without quotes it collapses all the white space into a single output line, if you issue an: echo "$table_prefix", you would see the match with all the other white-space that was output.
I'd recommend the following sed expression instead:
table_prefix=$(sed -n "s/^\$table_prefix.*'\([^']*\)'.*/\1/p" wp-config.php)
You should try
#!/bin/sh
table_prefix=$(awk -F"'" '/^\$table_prefix/{print $2}' wp-config.php)
echo $table_prefix
Does this one work for you?
awk -F\' '/^\$table_prefix/ {print $2}' wp-config.php
Update
If you are using shell scripting, there is no need to call up awk, grep:
#!/bin/sh
while read varName op varValue theRest
do
if [ "_$varName" = "_\$table_prefix" ]
then
table_prefix=${varValue//\'/} # Remove the single quotes
table_prefix=${table_prefix/;/} # Remove the semicolon
break
fi
done < wp-config.php
echo "Found: $table_prefix"

Resources