How to use a variable in a command that's creating another variable - linux

I created my basic variable from a read command (I've done this manually and using a script):
read NAME
I then want to use that NAME variable to search a file and create another variable:
STUDENT=$(grep $NAME <students.dat | awk -F: '/$NAME/ {print $1}')
If I run the command manually with an actual name from that students.dat file (and not $NAME), it executes and displays what I want. However, when I run this command (manually or from the script using $NAME), it returns blank, and I'm not sure why.

#user1615415: Try:
cat script.ksh
echo "Enter name.."
read NAME
STUDENT=$(awk -vname="$NAME" -F: '($0 ~ name){print $3}' student.dat)

Shell variables aren't interpolated in single quotes, only double quotes.
STUDENT=$(grep $NAME <students.dat | awk -F: "/$NAME/ {print \$1}")
$1 needs to be escaped to ensure it's not expanded by the shell, but by awk.

Related

Using awk to substitute variables into result of a ls command [duplicate]

This question already has answers here:
How do I use shell variables in an awk script?
(7 answers)
Closed 5 years ago.
I am trying to display which apps is deployed in each host. Using a bash script I had some success except I want to replace the following "hostname" part with the actual host name stored under the ${i} variable. I can't just substitute it because I cannot put a curly bracket inside another. EVEN if I can do it, I am still having trouble as ${i} will be replaced by the result of ls. How do I fix this?
hosts=(usa1 london2)
for i in ${hosts[#]}; do
echo ---${i}---
ssh ttoleung#${i} ls /apps | awk '{ printf("%s:%s\n", "hostname", $0) }'
done
Current output, based on code fragment above:
---usa01---
hostname:E2.gui
hostname:E1.server
---london2---
hostname:E1.gui
Desired output:
---usa01---
usa01:E2.gui
usa01:E1.server
---london2---
london2:E1.gui
Replace:
awk '{ printf("%s:%s\n", "hostname", $0) }'
With:
awk -v h="$i" '{ printf("%s:%s\n", h, $0) }'
-v h="$i" tells awk to create an awk variable h and assign to it the value of the shell variable $i.
Aside: we used h="$i" rather than h=$i because it is good practice to put shell variables inside double-quotes unless you want the shell to perform word-splitting and pathname expansion.
As an intro note, it is not a safe expand array names without double quotes unless for obvious reasons because doing so would split quoted strings in array that themselves have spaces
So change
for i in ${hosts[#]};
to
for i in "${hosts[#]}"; # Note the quoted array
Now, coming to your problem, you can pass bash variables to awk using its -v parameter. So change
ssh ttoleung#${i} ls /apps | awk '{ printf("%s:%s\n", "hostname", $0) }'
to
ssh ttoleung#${i} ls /apps | awk -v hname="${i}" '{ printf("%s:%s\n", hname, $0) }'
Here we pass shell parameter ${i} to awk variable hname.
Side Note: Don't parse ls output for the reasons mentioned [ here ]. In your case though, it doesn't make much of a difference.

Using awk command in Bash

I'm trying to loop an awk command using bash script and I'm having a hard time including a variable within the single quotes for the awk command. I'm thinking I should be doing this completely in awk, but I feel more comfortable with bash right now.
#!/bin/bash
index="1"
while [ $index -le 13 ]
do
awk "'"/^$index/ {print}"'" text.txt
done
Use the standard approach -- -v option of awk to set/pass the variable:
awk -v idx="$index" '$0 ~ "^"idx' text.txt
Here i have set the variable idx as having the value of shell variable $index. Inside awk, i have simply used idx as an awk variable.
$0 ~ "^"idx matches if the record starts with (^) whatever the variable idx contains; if so, print the record.
awk '/'"$index"'/' text.txt
# A lil play with the script part where you split the awk command
# and sandwich the bash variable in between using double quotes
# Note awk prints by default, so idiomatic awk omits the '{print}' too.
should do, alternatively use grep like
grep "$index" text.txt # Mind the double quotes
Note : -le is used for comparing numerals, so you may change index="1" to index=1.

Assign command output to variable in Bash?

I know this seems fairly trivial. But I have no idea where I am going wrong. I have a shell script where I download a package based on the input argument and then extract the package name. This is how I do it:
wget $1
echo $1 | awk -F/ '{print $NF}'
I run it like this bash scrip.sh http://apache.claz.org/phoenix/apache-phoenix-4.10.0-HBase-1.2/bin/apache-phoenix-4.10.0-HBase-1.2-bin.tar.gz
I download the package and then the second line splits the input variable along the / delimiter I get apache-phoenix-4.10.0-HBase-1.2-bin.tar.gz. Now I want to assign the result of the second line to a variable. I change my script to a dir=$($1 | awk -F/ '{print $NF}') and add an echo $dir to the script to see the result. However I keep running into this error : line 2: http://apache.claz.org/phoenix/apache-phoenix-4.10.0-HBase-1.2/bin/apache-phoenix-4.10.0-HBase-1.2-bin.tar.gz: No such file or directory
I tried wrapping the command into `` but the problem persists. I am not cd-ing into any directory so I have no idea why this error keeps showing up.

How to get the filename from a http link in linux?

In a shell script i have a variable $FILE_LINK, which contains the following string:
http://links.twibright.com/download/links-2.13.tar.gz
What i need is to get the filename from the link, and store it in a different variable, so the process would look similar to this:
Set variable $FILE_LINK
Get the last string after the last "/", in this case 'links-2.13.tar.gz'
Store the string in a variable $FILE_LINK_NAME
How i could achieve that?
If using BASH use:
file_link='http://links.twibright.com/download/links-2.13.tar.gz'
file_link_name="${file_link##*/}"
links-2.13.tar.gz
Or else use basename (not available on OSX):
file_link_name=$(basename "$file_link")
If not use this awk:
file_link_name=$(awk -F / '{print $NF}' <<< "$file_link")
Or using sed:
file_link_name=$(sed 's~.*/~~' <<< "$file_link")
PS: I'm avoiding all uppercase variable names in order to avoid clash with ENV variables.
LINK=http://links.twibright.com/download/links-2.13.tar.gz
FILE=`echo $LINK | awk -F "/" '{print $NF}'`
echo $FILE
The output is links-2.13.tar.gz
awk is a good tool for text processing.
https://en.wikipedia.org/wiki/AWK
-F set the separator
$NF means the last column

Setting an environment variable in csh

I have the following line at the first line in my script file:
#!/bin/sh
So I'm using csh.(?)
I wanto assign the output of the following to an environment variable:
echo $MYUSR | awk '{print substr($0,4)}'
I try:
set $MYVAR = echo $MYUSR | awk '{print substr($0,4)}'
But it doesn't work,
How can I do it? I want to do it in a sh file.
Your script should look like
#!/bin/csh
set MYVAR = `echo $MYUSR | awk '{print substr($0,4)}'`
echo $MYVAR
I don't have a way to test this right now, let me now if it doesn't work.
If you've inherited the basis of your script from someone else, with the #!/bin/sh,
then you have to find out if /bin/sh is really the bourne shell, or if it is a link to /bin/bash
You can tell that by doing
ls -l /bin/sh /bin/bash
if you get back information on files where the size is exactly the same, the you're really using bash, but called as /bin/sh
So try these 2 solutions
MYVAR=$(echo $MYUSR | awk '{print substr($0,4)}')
echo $MYVAR
AND
MYVAR=``echo $MYUSR | awk '{print substr($0,4)}``
echo $MYVAR
# arg!! only one pair of enclosing back-ticks needed,
# can't find the secret escape codes to make this look exactly right.
in all cases (csh) included, the back-ticks AND the $( ... ) are known as command substitution.
What every output comes from running the command inside, is substituted into the command line AND then the whole command is executed.
I hope this helps.
if it's /bin/sh it's bourne shell or bash, and use back quotes to execute something and this to assign that...
MYVAR=`echo $MYUSR | awk ...`
That script first line indicates that it should be interpreted by the Bourne shell (sh), not csh. Change it to
#!/bin/csh
The first line of your code shows clearly you are not using a csh. You are using a plain sh environment/shell. You have 2 options:
Either change the first line to #!/bin/csh OR
Keeping first line unchanged, update the code for setting the variable.
MYVAR=`echo $MYUSR | awk '{print substr($0,4)}`
echo $MYVAR
Let me know, if you get any error.

Resources