This question already has answers here:
How do I set a variable to the output of a command in Bash?
(15 answers)
Closed 2 years ago.
I want to assign the output of a shell command to a variable.
If I directly echo the command, the code will execute correctly:
for ((i=0; i<${#result[#]}; i++)); do
echo ${result[$i]} | awk '{print $1}'
done
But, if I assign it to a variable,
size=`${result[$i]} | awk '{print $1}'`
echo $size
Or
size=$(${result[$i]} | awk '{print $1}')
echo $size
They are not working.
How can I fix it?
You missed the echo
size=$(echo ${result[$i]} | awk '{print $1}')
Here the output the the echo is passed as input to the awk
The $() or back ticks just run the command and assign it to a variable, so when you just write
${result[$i]} | awk '{print $1}'
it won't give you anything as nothing is passed as input to the awk command.
Related
This question already has answers here:
How do I use shell variables in an awk script?
(7 answers)
Closed 1 year ago.
good morning, I am a newbie in the world of scripts and I have this problem and I don't know why it happens to me and why I have it wrong, thanks in advance.
For example, I have this command that searches for users with X less letters:
cut -d: -f1 /etc/passwd | awk 'length($1) <= 4'
It works correctly but when I substitute a 4 for a variable with the same value it doesn't do it well:
number=4
echo -e $(cut -d: -f1 /etc/passwd | awk 'length($1) <= $number')
The same error happens to me here too, when I search for users who have an old password
awk -F: '{if($3<=18388)print$1}' < /etc/shadow
Works, but when I use the variable it stops working
variable=18388
awk -F: '{if($3<=$variable)print$1}' < /etc/shadow
Consider using awk's ability to import variables via the -v option, eg:
number=4
cut -d: -f1 /etc/passwd | awk -v num="${number}" 'length($1) <= num'
Though if the first field from /etc/passwd contains white space, and you want to consider the length of the entire field, you should replace $1 with $0, eg:
number=4
cut -d: -f1 /etc/passwd | awk -v num="${number}" 'length($0) <= num'
Even better, eliminate cut and the subprocess (due to the pipe) and use awk for the entire operation by designating the input field separator as a colon:
number=4
awk -F':' -v num="${number}" 'length($1) <= num { print $1 }' /etc/passwd
You need to use double quotes:
echo -e $(cut -d: -f1 /etc/passwd | awk "length(\$1) <= $number")
In single quotes, variables are not interpreted.
Updated: Here is an illustrative example:
> X=1; echo '$X'; echo "$X"
$X
1
Update 2: as rightfully pointed out in the comment, when using double quotes one need to make sure that the variables that are meant for awk to interpret are escaped, so they are not interpreted during script evaluation. Command updated above.
Alternatively, this task could be done using only a single GNU sed one-liner:
num=4
sed -E "s/:.*//; /..{$num}/d" /etc/passwd
Another one-liner, using only grep would be
grep -Po "^[^:]{1,$num}(?=:)" /etc/passwd
but this requires a grep supporting perl regular expressions, for the lookahead construct (?=...).
This question already has answers here:
How to use variables in a command in sed?
(4 answers)
Closed 5 years ago.
I am a beginner at Linux and I'm trying to do a project which takes every line from a file.txt and replaces the third word with the first of each line. Here is my Shell code but it doesn't seem to work. It keeps replacing the third word with $field1 and not what's in it.
#!/bin/bash
while IFS=: read -r field1;do
sed -e 's/[^:]*[^:]/$field1/3'
done < file.txt
Try this, this will replace in the same file:
#!/bin/sh
while read -r line
do
first=`echo $line | awk -F':' '{ print $1 }'`
last=`echo $line | awk -F':' '{ print $3 }'`
echo $line | sed "s/$last/$first/"
done < file.txt
Input file :
ashish:is:good
navin:is:good
how:are:you
Output :
ashish:is:ashish
navin:is:navin
how:are:how
Make note of the single quotation marks. Place them around the field1 variable and so:
sed -e 's/[^:]*[^:]/'$field1'/3'
This question already has answers here:
How do I use shell variables in an awk script?
(7 answers)
Closed 6 years ago.
I want to add a word at the end of each line in my text file which is stored in variable. whenever i execute shell script instead of concatenate content stored in variable variable itself get concatenated. Below is the example for same:
Input:
cat output2.txt
12345
att1=Ramesh^Mumbai
awk '{print $0"^$att1"}' output2.txt >output3.txt
output:
12345^att1
Desired Output:
12345^Ramesh^Mumbai
Try this:
awk -v att1='Ramesh^Mumbai' -v OFS='^' '{print $0,att1}'
-v option allows to pass variable to awk
OFS is the output field separator (that will replace the , in the print statement by ^)
man awk:
-v var=val
Assign the value val to the variable var, before execution of
the program begins. Such variable values are available to the
BEGIN block of an AWK program.
you can use this;
#!/bin/bash
att1=Ramesh^Mumbai
awk -v att1=$att1 '{print $0"^"att1}' output.txt > output3.txt
Example;
user#host:/tmp$ cat output.txt
12345
abab
dafadf
adfaf
user#host:/tmp$, ./test.sh
user#host:/tmp$ cat output3.txt
12345^Ramesh^Mumbai
abab^Ramesh^Mumbai
dafadf^Ramesh^Mumbai
adfaf^Ramesh^Mumbai
This question already has answers here:
Using awk with variables
(3 answers)
Closed 8 years ago.
I have following variable set in my unix environment. If i try to use it in awk command its not working but the same command is working when i dont use $b variable
$b="NEW"
when i try following command it is not working
echo "$a" | tr [a-z] [A-Z] |awk -v RS=, '/TABLE/&&/CREATE/&&/`echo ${b}`/{print $NF}'
But, if i replace the $b value to NEW as below its working
echo "$a" | tr [a-z] [A-Z] |awk -v RS=, '/TABLE/&&/CREATE/&&/NEW/{print $NF}'
You cannot use a bash var inside awk like that. Instead, use:
echo "$a" | tr [a-z] [A-Z] | awk -v RS=, -v myvar=$b '/TABLE/&&/CREATE/&& $0~myvar {print $NF}'
See an example:
$ var="hello"
$ awk -v text=$var 'BEGIN{print text}'
hello
Also, to me it works with tr 'a-z' 'A-Z' instead of tr [a-z] [A-Z]. And based on Mark Setchell suggestion, you can skip it by using the IGNORECASE = 1:
echo "$a" | awk -v RS=, -v myvar=$b 'BEGIN{IGNORECASE=1} /TABLE/&&/CREATE/&& $0~myvar {print $NF}'
Regarding your question:
if i replace the $b value to NEW as below its working
It works because the value of your variable is NEW and what you end up doing is using that in the regex, which is exactly how it is supposed to be done.
about your second question:
can not use unix $variable in awk command
You cannot use shell variables in awk like that. You need to create an awk variable by using -v option and assigning your bash variable.
awk -v awkvar="$bashvar" '/ /{ ... }'
This makes your existing syntax as:
echo "$a" | tr [a-z] [A-Z] | awk -v RS=, -v var="$b" '/TABLE/&&/CREATE/&&/var/{print $NF}'
This again won't work because inside /../ variables are not interpolated, meaning they are considered literally. So, you need to do:
echo "$a" | tr [a-z] [A-Z] |awk -v RS=, -v var="$b" '/TABLE/&&/CREATE/&&$0~var{print $NF}'
This question already has an answer here:
Shell script, saving the command value to a variable
(1 answer)
Closed 9 years ago.
Can anyone help me out with this problem?
I'm trying to save the awk output into a variable.
variable = `ps -ef | grep "port 10 -" | grep -v "grep port 10 -"| awk '{printf "%s", $12}'`
printf "$variable"
EDIT: $12 corresponds to a parameter running on that process.
Thanks!
#!/bin/bash
variable=`ps -ef | grep "port 10 -" | grep -v "grep port 10 -" | awk '{printf $12}'`
echo $variable
Notice that there's no space after the equal sign.
You can also use $() which allows nesting and is readable.
I think the $() syntax is easier to read...
variable=$(ps -ef | grep "port 10 -" | grep -v "grep port 10 -"| awk '{printf "%s", $12}')
But the real issue is probably that $12 should not be qouted with ""
Edited since the question was changed, This returns valid data, but it is not clear what the expected output of ps -ef is and what is expected in variable.
as noted earlier, setting bash variables does not allow whitespace between the variable name on the LHS, and the variable value on the RHS, of the '=' sign.
awk can do everything and avoid the "awk"ward extra 'grep'. The use of awk's printf is to not add an unnecessary "\n" in the string which would give perl-ish matcher programs conniptions. The variable/parameter expansion for your case in bash doesn't have that issue, so either of these work:
variable=$(ps -ef | awk '/port 10 \-/ {print $12}')
variable=`ps -ef | awk '/port 10 \-/ {print $12}'`
The '-' int the awk record matching pattern removes the need to remove awk itself from the search results.
variable=$(ps -ef | awk '/[p]ort 10/ {print $12}')
The [p] is a neat trick to remove the search from showing from ps
#Jeremy
If you post the output of ps -ef | grep "port 10", and what you need from the line, it would be more easy to help you getting correct syntax