bash / Variable value is empty after the loop - bash

I'm new to bash and try a simple loop but the value of my variable is being lost after it and I can not understand why - I have looked at few similar issues but they are all related to subshell execution of a while loop . I'm not doing but still facing issues - can someone explain me where is my mistake ?
#!/bin/bash
check_ss ()
{
command_list | awk '{print $1 $9}' > ss.out
for i in {1..8}
do grep -Pa "\x3$i" ss.out > ss$i.out
if grep -w "NotStarted" ss$i.out
then
ss$i=0
else
ss$i=1
fi
done
}
check_ss
echo $ss1
echo $ss2
echo $ss3
echo $ss4
I'm getting this on execution :
[root#lubo ~]# ./ss.sh
./ss.sh: line 21: ss1=1: command not found
./ss.sh: line 21: ss2=1: command not found
./ss.sh: line 21: ss3=1: command not found
./ss.sh: line 21: ss4=1: command not found
./ss.sh: line 21: ss5=1: command not found
./ss.sh: line 21: ss6=1: command not found
./ss.sh: line 21: ss7=1: command not found
./ss.sh: line 21: ss8=1: command not found
Thanks in advance

You need to use declare to dynamically construct a variable name.
declare "ss$i=0"

An array would be a better alternative to dynamic variable names.
check_ss() {
ss=()
command_list | awk '{print $1 $9}' > ss.out
for i in {1..8}; do
grep -Pa "\x3$i" ss.out > ss$i.out
if grep -w "NotStarted" ss$i.out; then
ss[$i]=0
else
ss[$i]=1
fi
done
}
check_ss
echo ${ss[1]}
echo ${ss[2]}
echo ${ss[3]}
echo ${ss[4]}
You could also get rid of the temporary files.
check_ss() {
ss=()
command_list | awk '{print $1 $9}' > ss.out
for i in {1..8}; do
if grep -Pa "\x3$i" ss.out | grep -w "NotStarted"; then
ss[$i]=0
else
ss[$i]=1
fi
done
}
I don't know what your input looks like exactly, but you might even be able to simplify it further to something like:
check_ss() {
ss=()
while read i; do
ss[$i]=1
done < <(command_list | awk '$9=="NotStarted" {print $1}')
}
or if you just want a list of the NotStarted numbers,
ss=(command_list | awk '$9=="NotStarted" {print $1}')
echo "${ss[#]}"

Related

Why doesn't "sed" pick up on command?

`When using sed and trying to pull out a specific line, it looses the p portion of "sed -n (x)p test.txt"
I'm trying to look at a line and see if its A or B.
sed -n 3p test.txt
works fine, but i'm trying to do:
sed -n $(Count) test.txt
This doesn't work
sed -n $($Count)p test.txt
Doesn't work
Count=$(cat -n test.txt | grep -o [0-9]* | tail -1)
until [ $Count = 0 ]; do
if [[ $(sed -n $(Count)p test.txt) = Him ]] || [[ $(sed -n $(Count)p model.txt) = He ]]
then
echo "This is a Boy Word"
elif [[ $(sed -n $(Count)p model.txt) = Her ]] || [[ $(sed -n $(Count)p model.txt) = She ]]
then
echo "This is an Girl Word"
fi
let Count=Count-1
sleep 1
done
I'm expecting :
This is a Boy Word
This is a Boy Word
This is a Girl Word
This is a Girl Word...
Until it has gone through all the lines,
However I'm getting (with sed -n $($Count)p test.txt)
Line 17: 3: command not found
Line 20: 3: command not found
Line 17: 2: command not found
Line 17: 2: command not found
Or (with sed -n $(Count)p test.txt
Line 17: Count: command not found
Line 20: Count: Command not found
Line 17: Count: Command not Found
Line 20: Count: command not found
You need to use the full form ${Count} to separate the variable name from an adjacent character.
sed -n ${Count}p test.txt
Or, simply quote the parameter expansion:
sed -n "$Count"p test.txt

unexpected EOF while looking for matching error

I am running below script and getting
error script.sh: line 9: unexpected EOF while looking for matching `''
script.sh: line 15: syntax error: unexpected end of file.
Though I tried to run line 9 manually n it runs without error.
alias gxt="awk -F "_" '{print \$1}' test | uniq"
count = $(cat test | awk -F "_" '{print $1} | uniq | wc -l)
for i in {1..count};
do
User=$(gxt | head -n $i)
recharge=$(grep -E "$User.recharge" test| awk -F "_" '{print $3}' | xargs )
total1=( $((${recharge// /+})))
sales=$(grep -E "$User.sale" test| awk -F "_" '{print $3}' | xargs )
total2=( $((${sales// /+})))
balance=`expr $total1 - $total2`
echo $User.balance.$balance >> result
done
Other than the issues already reported and those exposed by shellcheck, there is another issue:
for i in {1..count};
'count' cannot be a variable. It can only be a constant.
Change it to
for ((i = 1; i <= count; i++)); do whatever ; done
count=$(cat test | awk -F "_" '{print $1}` | uniq | wc -l)
missing ' at the end of {print $1}
Inadvertently added spaces around =

awk: syntax error near unexpected token `('

I tried to assign the output of an awk command to a variable:
USERS=$(awk '/\/X/ {print $1}' <(w))
This line is part of the following script:
#!/bin/sh
INTERFACE=$1 # The interface which is brought up or down
STATUS=$2 # The new state of the interface
case "$STATUS" in
up) # $INTERFACE is up
if pidof dropbox; then
killall dropbox
fi
USERS=$(awk '/\/X/ {print $1}' <(w))
for user in $USERS; do
su -c "DISPLAY=$(awk '/\/X/ {print $11}' <(w)) dropboxd &" $user
done
;;
down) # $INTERFACE is down
;;
esac
However, I get the following error:
script: command substitution: line 14: syntax error near unexpected token `('
script: command substitution: line 14: `awk '/\/X/ {print $1}' <(w))'
All brackets are closed. Where is the syntax error?
I'm assuming because you are using #!/bin/sh and not #!/bin/bash that process substitution is not available (or you have a version of bash that doesn't support process subsitiution, pre 4.X.X). Switch to bash or just pipe w to your awk command:
USERS=$(w | awk '/\/X/ {print $1}')

error in awk of shell script

I am getting the below error ith my code.What is missing in it? My goal is to print 13.0.5.8 in $version
#!/bin/ksh
file="abc_def_APP_13.0.5.8"
if echo "$file" | grep -E "abc_def_APP"; then
echo "Version found: $file"
version1=(echo $file | awk -F_ '{print $NF}' | cut -d. -f1-3)
version2=(echo $file | awk -F_ '{print $NF}' | cut -d. -f4-)
echo $version1
echo $version2
version=$version$version2
echo $version
else
echo "Version not found"
fi
Please find below the error:
./version.sh: line 7: syntax error near unexpected token `|'
./version.sh: line 7: ` version1=(echo $file | awk -F_ '{print $NF}' | cut -d. -f1-3)'
./version.sh: line 9: syntax error near unexpected token `|'
./version.sh: line 9: ` version2=(echo $file | awk -F_ '{print $NF}' | cut -d. -f4-)'
./version.sh: line 18: syntax error near unexpected token `else'
There's no need for awk at all. Just trim every character before the last underscore, like so:
file="abc_def_APP_13.0.5.8"
version="${file##*_}"
echo "$version"
See http://mywiki.wooledge.org/BashFAQ/073 for documentation on this technique, or see "parameter expansion" in bash's own docs.
To treat the last segment separately is also straightforward:
file="abc_def_APP_13.0.5.8"
version="${file##*_}" # result: 13.0.5.8
version_end="${version##*.}" # result: 8
version_start="${version%.*}" # result: 13.0.5
echo "${version_start}/${version_end}" # result: 13.0.5/8
Because this happens internally to bash, without executing any external commands (such as awk), it should be considerably faster to execute than other approaches given.
The problem is your backticks are missing $ you need to fix the following two lines like so:
version1=$(echo $file | awk -F_ '{print $NF}' | cut -d. -f1-3)
version2=$(echo $file | awk -F_ '{print $NF}' | cut -d. -f4-)
This will fix the syntactical errors. The following line doesn't make much sense as $version hasn't been initialize yet:
version=$version$version2
Did you mean:
version="${version1}.${version2}"
A side note you are using the -E option with grep but you aren't using any extended regexp features, in fact you are doing a fixed string string search so -F is more appropriate. You probably also want to use the -q option to suppress the output from grep.
Personally I would do:
file="abc_def_APP_13.0.5.8"
echo "$file" | awk '/abc_def_APP/{print "Version found: "$0;
print $4,$5,$6;
print $7;
print $4,$5,$6,$7;
next}
{print "Version not found"}' FS='[_.]' OFS=.
If you just want the version number in the variable version then why not simply:
version=$(echo "$file" | grep -o '[0-9].*')
It can all be done in a single awk command and without additional cut command. Consider following command:
read version1 version2 < <(echo $file|awk -F "[_.]" '{
printf("%s.%s.%s ", $4, $5, $6); printf("%s", $7);
for (i=8; i<=NF; i++) printf(".%s", $i); print ""}')
echo "$version1 :: $version2"
OUTPUT
13.0.5 :: 8

Syntax error near unexpected token `done'

I run my shell script but return a error "syntax error near unexpected token `done'", I wonder why it is ? The important thing is I can run it in another computer...
See my code below:
input=$1
folder=$2
output=$3
while read line
do
url=`echo $line | awk -F'\t' '{print $2}'`
id=`echo $line | awk -F'\t' '{print $2}' | sed 's/http:\/\/buy.yahoo.com.tw\/gdsale\/gdsale.asp?gdid=//g'`
ans=`echo $line | awk -F'\t' '{print $3}'`
flag=`grep "$ans" $folder/$id".spec"`
if [ -n "$flag" ]; then
echo "yes $line" >> $3
else
echo "no $line" >> $3
fi
done < $input
Thanks!
If it runs on one machine but not another, then there are differences in the script files on the different machines. Perhaps you have different line endings on one machine -- check them both with dos2unix

Resources