bash: unexpected token 283 in conditional command - bash

i input command in the bash shell:
#!/bin/bash
[[ a>2 ]];echo $?
I get 0
and another command:
#!/bin/bash
[[ 3>2 ]];echo $?
I get
bash: unexpected token 283 in conditional command
bash: syntax error near `3>'
Why I get the err ?
How do I use > < in the [[ ]] ?
I am more curious, in [[]] how to use > < . [[ a>2 ]];echo $? do not add spaces, but [[ 3 > 2 ]] must be added space, more curious about the reasons
thank you!

As the man page for bash builtins states: "Each operator and operand
must be a separate argument."
Also your variable a should be $a
Here is example :
# Returns true
$ a=10; [[ "$a" -gt 1 ]]; echo "$?"
0
# Returns false
$ a=10; [[ "$a" -gt 12 ]]; echo "$?"
1
Following may help you
Integer comparison operators
| Operator | Description | Example |
|----------|-----------------------------|----------------------------------------------------------|
| -eq | Is Equal To | if [ $1 -eq 200 ] |
| -ne | Is Not Equal To | if [ $1 -ne 1 ] |
| -gt | Is Greater Than | if [ $1 -gt 15 ] |
| -ge | Is Greater Than Or Equal To | if [ $1 -ge 10 ] |
| -lt | Is Less Than | if [ $1 -lt 5 ] |
| -le | Is Less Than Or Equal To | if [ $1 -le 0 ] |
| == | Is Equal To | if (( $1 == $2 )) [Note: Used within double parentheses] |
| != | Is Not Equal To | if (( $1 != $2 )) |
| < | Is Less Than | if (( $1 < $2 )) |
| <= | Is Less Than Or Equal To | if (( $1 <= $2 )) |
| > | Is Greater Than | if (( $1 > $2 )) |
| >= | Is Greater Than Or Equal To | if (( $1 >= $2 )) |
String comparison operators
| Operator | Description | Example |
|----------|------------------------------------|-----------------|
| = or == | Is Equal To | if [ $1 == $2 ] |
| != | Is Not Equal To | if [ $1 != $2 ] |
| > | Is Greater Than (ASCII comparison) | if [ $1 > $2 ] |
| >= | Is Greater Than Or Equal To | if [ $1 >= $2 ] |
| < | Is Less Than | if [ $1 < $2 ] |
| <= | Is Less Than Or Equal To | if [ $1 <= $2 ] |
| -n | Is Not Null | if [ -n $1 ] |
| -z | Is Null (Zero Length String) | if [ -z $1 ] |

Related

How to pass files as argument in Shellscript

so this is a question to a script that I already questioned about in a previous question :
Link : Typesort Shellscript in Unix
So now below is my updated version of the Script and my new question is, how do I have to change it to pass multiple files as args to sort these?
And is there an easier option to accept arguments like "./typesort -rnv instead of -r -n -v" ?
I feel like my solution is not optimal for this problem.
Thanks for your replies.
#!/bin/bash
#A shell script with in- and output
usage()
{
cat <<EOF
$typesort [OPTIONS]
Sort filenames by file type given by
the ''file'' command
$typesort --version Print version number
OPTIONS:
-t sort text files only
-n sort non-text files only
-r reverse sort order
-v --verbose print debugging messages
EOF
}
# ----------------------------------------------
#flags
tflag=0
nflag=0
rflag=0
vflag=0
bflag=0
# -------------------------------------------------
sort_nA()
{
if [ "$vflag" == 1 ]
then
echo "sort_nA"
echo "file * | sort -t':' -k 2"
fi
file * | sort -t':' -k 2
}
# #######################################################
sort_r()
{
if [ "$vflag" == 1 ]
then
echo "sort_r"
echo "file * | sort -t':' -k 2 -r"
fi
file * | sort -t':' -k 2 -r
}
# #######################################################
sort_t()
{
if [ "$vflag" == 1 ]
then
echo "sort_t"
echo "file * | grep "ASCII text" | sort -t':' -k 2"
fi
file * | grep "ASCII text" | sort -t':' -k 2
}
# #######################################################
sort_n()
{
if [ "$vflag" == 1 ]
then
echo "sort_n"
echo "file * | grep -v "ASCII text" | sort -t':' -k 2"
fi
file * | grep -v "ASCII text" | sort -t':' -k 2
}
# #######################################################
sort_rt()
{
if [ "$vflag" == 1 ]
then
echo "sort_rt"
echo "file * | grep "ASCII text" | sort -t':' -k 2 -r"
fi
file * | grep "ASCII text" | sort -t':' -k 2 -r
}
# #######################################################
sort_rn()
{
if [ "$vflag" == 1 ]
then
echo "sort_rn"
echo "file * | grep -v "ASCII text" | sort -t':' -k 2 -r"
fi
file * | grep -v "ASCII text" | sort -t':' -k 2 -r
}
# #######################################################
# main
while true
do
if [ "$1" == "-t" ]
then
tflag=1
elif [ "$1" == "-n" ]
then
nflag=1
elif [ "$1" == "-r" ]
then
rflag=1
elif [ "$1" == "-v" ]
then
vflag=1
else
#at least 1 arg, let's check it
case $1 in
"-h" | "--help") #display help text
bflag=1
usage
break
;;
"--version") #display version number
echo "version number 0.1"
bflag=1
break
;;
"")
break
;;
"-rt" | "-tr")
rflag=1
tflag=1
;;
"-rn" | "-nr")
rflag=1
tflag=1
;;
"-rv" | "-vr")
rflag=1
vflag=1
;;
"-vt" | "-tv")
tflag=1
vflag=1
;;
"-vn" | "-nv")
nflag=1
vflag=1
;;
"-tn" | "-nt")
tflag=1
nflag=1
"-rtn" | "-trn" | "-tnr" | "-rnt" | "-nrt" | "-ntr")
rflag=1
tflag=1
nflag=1
;;
"-vtn" | "-tvn" | "-tnv" | "-vnt" | "-nvt" | "-ntv")
vflag=1
tflag=1
nflag=1
;;
"-rvn" | "-vrn" | "-vnr" | "-rnv" | "-nrv" | "-nvr")
vflag=1
rflag=1
nflag=1
;;
"-rvt" | "-vrt" | "vtr" | "-rtv" | "-trv" | "-tvr")
vflag=1
rflag=1
tflag=1
;;
"-rvtn" | "-rtvn" | "-rtnv" | "-rvnt" | "-rnvt" | "-rntv" | "-vrtn" | "-vtrn" | "-vtnr" | "-vrnt" | "-vnrt" | "-vntr" | "-trvn" | "-tvrn" | "-tvnr" | "-trnv" | "-tnrv" | "-tnvr" | "-nrtv" | "-ntrv" | "-ntvr" | "-nrvt" | "-nvrt" | "-nvtr")
vflag=1
rflag=1
tflag=1
nflag=1
;;
*) #anything else not valid
echo "Invalid option: ยง1"
;;
esac
fi
shift
done
if [ "$vflag" == 1 ]
then
echo "tflag = $tflag"
echo "nflag = $nflag"
echo "rflag = $rflag"
echo "bflag = $bflag"
fi
if [ "$bflag" == 1 ]
then
bflag=1 # nothing should happen
elif [ "$rflag" == 1 ] && [ "$tflag" == "$nflag" ]
then
sort_r
elif [ "$rflag" == 1 ] && [ "$tflag" == 1 ]
then
sort_rt
elif [ "$rflag" == 1 ] && [ "$nflag" == 1 ]
then
sort_rn
elif [ "$tflag" == "$nflag" ]
then
sort_nA
elif [ "$tflag" == 1 ]
then
sort_t
elif [ "$nflag" == 1 ]
then
sort_n
fi
exit 0
Just wrap the body of your script between
for arg in "$#"
do
..... # your script body goes here
done
and use $arg instead of $1. You can then pass several arguments, either explicitly, and/or using filename genaration:
your_script.sh file1 file2 other_files* file3
While your execution your script shell
./Yourshellscript.sh file1 file2 ..

How to fix "syntax error near unexpected token `done' " in a nested loop in bash?

I am writing a script that will loop through columns to find an instance of a word.
I decided I do it through nested loops and after executing my code, I get this error:
./gallupscript.sh: line 115: syntax error near unexpected token done'
./gallupscript.sh: line 115:done'
Here is the area where my code fails:
token=2 #token is the column number
starter=0
s1="First" ; s2="Second" ; s3="Third" ; s4="Fourth" ; s5="Fifth"
s=s ; a=1
while [ $token -le 6 ]
do
cat gallup.csv | cut -d',' -f"$token" | grep -n $strength1 | cut -d':' -f1 > str1
if [ -s str1 ]
then
for i in $(cat str1)
do
if [[ $i -ne $number && $starter -eq 0 ]]
then
save=$(cat gallup.csv | head -$i | tail +$i | cut -d',' -f1)
s=s ; s+=$a ; starter=1
printf "-- $strength1 --"
printf "${!s} Strength: $save"
elif [[ $i -ne $number && $starter -ne 0 ]]
then
save=$(cat gallup.csv | head -$i | tail +$i | cut -d',' -f1)
printf ", $save"
fi
done
starter=0
a=$((a+1))
token=$((token+1))
echo #new line
done
This code is expected to output the names (in first columns) where the word is matched with the one I am searching for.
You are not closing your if statement, it doesn't have to do with for.
Use the following code instead:
token=2 #token is the column number
starter=0
s1="First" ; s2="Second" ; s3="Third" ; s4="Fourth" ; s5="Fifth"
s=s ; a=1
while [ $token -le 6 ]
do
cat gallup.csv | cut -d',' -f"$token" | grep -n $strength1 | cut -d':' -f1 > str1
if [ -s str1 ]
then
for i in $(cat str1)
do
if [[ $i -ne $number && $starter -eq 0 ]]
then
save=$(cat gallup.csv | head -$i | tail +$i | cut -d',' -f1)
s=s ; s+=$a ; starter=1
printf "-- $strength1 --"
printf "${!s} Strength: $save"
elif [[ $i -ne $number && $starter -ne 0 ]]
then
save=$(cat gallup.csv | head -$i | tail +$i | cut -d',' -f1)
printf ", $save"
fi
done
fi # <------------ add this line
starter=0
a=$((a+1))
token=$((token+1))
echo #new line
done

Converting multiple lines of bash in to a single line

Is there any short and easy way to convert multiple lines of script in to a single line to be parsed in a eval command?
ie
getent group | cut -f3 -d":" | sort -n | uniq -c |\
while read x ; do
[ -z "${x}" ] && break
set - $x ; if [ $1 -gt 1 ]; then
grps=`getent group | nawk -F: '($3 == n) { print $1 }' n=$2 | xargs` ; echo "Duplicate GID ($2): ${grps}" ; fi done
one_line=`cat your_script_file | sed ":a s/[\]$//; N; s/[\]$//; s/\n/ /; t a ;"`
echo $one_line

Why is this giving me an error ? count is

ls>out
count="$(ls|wc -l)"
for i in {1..$count-2}
do
if[ "$(cat out|head -$count | tail -1)" != "rename.sh" ]; then
mv "$1$count$2" | cat out | head -$count | tail -1
fi
done
I really don't get why is not working...
ls>out
count="$(ls|wc -l)"
for i in {1..$count-2}
do
if [ "$(cat out|head -$count | tail -1)" != "rename.sh" ]; then
mv "$1$count$2" | cat out | head -$count | tail -1
fi
done
put a space between if and '[' , the script will be work.

Calculate Bearing with lat and long but do not have ATAN2 function

I've been searching the web trying to find a way to calculate bearing without using the ATAN2 function. I found the this code but I can't make it work. I trying to validate the equation before I use it in my PLC program but the numbers are not coming up correctly. Any help is appreciated.
y = sin(lon2-lon1)*cos(lat2)
x = cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon2-lon1)
if y > 0 then
if x > 0 then tc1 = arctan(y/x)
if x < 0 then tc1 = 180 - arctan(-y/x)
if x = 0 then tc1 = 90
if y < 0 then
if x > 0 then tc1 = -arctan(-y/x)
if x < 0 then tc1 = arctan(y/x)-180
if x = 0 then tc1 = 270
if y = 0 then
if x > 0 then tc1 = 0
if x < 0 then tc1 = 180
if x = 0 then [the 2 points are the same]
Gene
Your equation is fine.
Here is a working implementation on bash.
# /bin/bash
DEG_PER_RAD=$(echo "scale=10; 180 / 3.141592653589" | bc)
function atan2 {
if [ $(echo "scale=10; $1 > 0" | bc -l) -eq 1 ]
then
if [ $(echo "scale=10; $2 > 0" | bc -l) -eq 1 ]
then
a2=$(echo "scale=10; a($1 / $2)" | bc -l)
fi
if [ $(echo "scale=10; $2 < 0" | bc -l) -eq 1 ]
then
a2=$(echo "scale=10; 3.141592653589 - a(-1 * $1 / $2)" | bc -l)
fi
if [ $(echo "scale=10; $2 == 0" | bc -l) -eq 1 ]
then
a2=$(echo "scale=10; 3.141592653589 / 2" | bc -l)
fi
fi
if [ $(echo "scale=10; $1 < 0" | bc -l) -eq 1 ]
then
if [ $(echo "scale=10; $2 > 0" | bc -l) -eq 1 ]
then
a2=$(echo "scale=10; -1 * a(-1 * $1 / $2)" | bc -l)
fi
if [ $(echo "scale=10; $2 < 0" | bc -l) -eq 1 ]
then
a2=$(echo "scale=10; a($1 / $2) - 3.141592653589" | bc -l)
fi
if [ $(echo "scale=10; $2 == 0" | bc -l) -eq 1 ]
then
a2=$(echo "scale=10; 3 * 3.141592653589 / 2" | bc -l)
fi
fi
if [ $(echo "scale=10; $1 == 0" | bc -l) -eq 1 ]
then
if [ $(echo "scale=10; $2 > 0" | bc -l) -eq 1 ]
then
a2=0
fi
if [ $(echo "scale=10; $2 < 0" | bc -l) -eq 1 ]
then
a2=$(echo "scale=10; 3.141592653589" | bc -l)
fi
if [ $(echo "scale=10; $2 == 0" | bc -l) -eq 1 ]
then
a2=0
fi
fi
}
function get_bearing {
rad_lat1=$(echo "scale=9; ("$1" / $DEG_PER_RAD)" | bc)
rad_lon1=$(echo "scale=9; ("$2" / $DEG_PER_RAD)" | bc)
rad_lat2=$(echo "scale=9; ("$3" / $DEG_PER_RAD)" | bc)
rad_lon2=$(echo "scale=9; ("$4" / $DEG_PER_RAD)" | bc)
dLon=$(echo "scale=10; $rad_lon2 - $rad_lon1" | bc -l)
y=$(echo "scale=10; s($dLon) * c($rad_lat2)" | bc -l)
x=$(echo "scale=10; (c($rad_lat1) * s($rad_lat2)) - (s($rad_lat1) * c($rad_lat2) * c($dLon))" | bc -l)
atan2 $y $x
bearing=$(echo "scale=10; $DEG_PER_RAD * $a2" | bc -l)
}
get_bearing 49.624196795 6.1256280094 49.6241653669 6.1242621755
echo "Bearing is "$bearing
Regarding PLC I have no experiance so I can't help you. Sorry

Resources