Case statement in shell script - bash

I have the following problem.
How can I loop trough a .csv file and do an something when the ID of $d is a certain number.
I made one with an if elseif like this that works fine:
while read a b c d e
do
if [ "$d" = "20.000" ]
then
ACTION
elif [ "$d" = "24.000" ]
then
ACTION
elif [ "$d" = "28.000" ]
then
ACTION
elif [ "$d" = "32.000" ]
then
ACTION
elif [ "$d" = "53.000" ]
then
ACTION
elif [ "$d" = "8.000" ]
then
ACTION
elif [ "$d" = "36.000" ]
then
ACTION
elif [ "$d" = "37.000" ]
then
ACTION
Now this code becomes very long and was looking for a nicer solution.
I have the following, but I get the following errors.
line 24: syntax error near unexpected token of' line 24: case $d of'
Here is my code:
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read a b c d e
#a=name
#b=northing
#c=easting
#d=id
#e=color
do
read d
case $d of
exit) break ;;
20.000) echo "NBUOY" ;;
24.000) echo "EBUOY" ;;
28.000) echo "SBUOY" ;;
32.000) echo "WBUOY" ;;
53.000) echo "RBUOY" ;;
8.000) echo "RBUOY" ;;
36.000) echo "RBUOY" ;;
37.000) echo "RBUOY" ;;
55.000) echo "RBUOY" ;;
10.000) echo "RBUOY" ;;
14.000) echo "GBUOY" ;;
16.000) echo "GBUOY" ;;
6.000) echo "YSBUOY" ;;
4.000) echo "YSBUOY" ;;
1.000) echo "YSBUOY" ;;
5.000) echo "YSBUOY" ;;
*) echo "Unknown response, enter a number 1-12 or type 'exit' to quit" ;;
esac
done
What is going wrong? and is this even possible?

Related

Why am I getting unexpected-token error in this script?

I want to loop through all the files in the directory and check their perms (if user wants) but for some reason I'm getting this error:
./perms.sh: line 12: syntax error near unexpected token `;;'
./perms.sh: line 12: ` r) if [ -r $i ] then echo 'True' else echo 'False' fi ;;'
here is my code:
#!/bin/bash
for i in *
do
echo "Do you want to check rights for $i (y/n)"
read marzi
if [ $marzi = 'y' ]
then
echo 'which commands to check? '
read check
case $check in
r) if [ -r $i ] then echo 'True' else echo 'False' fi ;;
w) if [ -w $i ] then echo 'True' else echo 'False' fi ;;
x) if [ -x $i ] then echo 'True' else echo 'False' fi ;;
*) echo 'unrecognized!' ;;
esac
else
echo "skipped $i"
fi
done
does this have something to do with apostrophe?
maybe correct inline if format should be
if [ -r $i ]; then echo 'True'; else echo 'False'; fi
make sure to make change for r and w and x

Loop Script throws 0 by executing touch

I'm writing a script that makes a while loop for me, that I doesn't have to write a one line while loop again and again.
Short explanation:
The command "loop" will execute the command parameter -n times and with -p seconds pause. You can use -e to echo the command and not execute it. -v to show all parameters. Additionally its possible to use the iterator of the while loop.
Playing around with it, I've found a bug.
loop --verbose --times 5 'touch testfile$i'
#loop the touch command 5 times and generate the testfiles 0 to 4
same as:
loop -v -n 5 'touch testfile$i'
It generate "testfile0" to "testfile4" but also a file named "0"
Do somebody know why the file "0" will be generated?
And what do you think about a command like that? Would you like to use it?
Best
Steven
#!/bin/bash
# easy to use loop command
#
# Autor: Steven Wagner
# Date: 22 June 2018
# Version: 0.1
TIMES=0
FREQUENCY=0
PAUSE="0"
VERBOSE=false
ECHOONLY=false
SILENCE=false
POSITIONAL=()
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-n|--times)
temp="$2"
if [[ $temp =~ ^[[:digit:]]+$ ]];
then
TIMES=$temp
else
echo "ERROR: value is not a digit"
exit
fi
shift # past argument
shift # past value
;;
-p|--pause)
#PAUSE="$2"
temp="$2"
PAUSE=$temp
#if [[ $temp =~ ^[[:digit:]]+$ ]];
#then
# PAUSE=$temp
#else
# echo "ERROR: value is not a digit"
# exit
#fi
shift # past argument
shift # past value
;;
-v|--verbose)
VERBOSE=true
shift # past argument
;;
-e|--echo-only)
ECHOONLY=true
shift # past argument
;;
-s|--silence)
SILENCE=true
shift # past argument
;;
--*)
echo "Error \"$key\" not known"
shift #past argument
;;
-*)
i=0
while [[ $i -lt ${#key}-1 ]]
do
char=${key:$[$i+1]:1}
case $char in
v)
VERBOSE=true
;;
e)
ECHOONLY=true
;;
s)
SILENCE=true
;;
esac
(( i++ ))
done
shift # past argument
;;
*) # unknown option
POSITIONAL+=("$1") # save it in an array for later
shift # past argument
;;
esac
done
set -- "${POSITIONAL[#]}" # restore positional parameters
#Pause make sleep command
pause=""
if [ $PAUSE > 0 ]
then
pause="sleep $PAUSE"
fi
#times make while control-command
times=""
if [ $TIMES != 0 ]
then
times="[ \$i -lt \$TIMES ]"
else
times="true" #infinity loop
fi
#Echo Only
command=$#
if $ECHOONLY
then
command="echo $#"
fi
#Silence
silence=""
if $SILENCE && ! $ECHOONLY
then
silence="&>/dev/null"
fi
if $VERBOSE
then
echo "pause = $PAUSE"
if [ $TIMES != 0 ]
then
echo "times = $TIMES"
else
echo "times = infinity"
fi
if $ECHOONLY; then echo "echo only = yes"; fi
if $SILENCE; then echo "silence = yes"; fi
echo "command = '$#' $silence"
echo
fi
#start the loop
timestamp=$(date +%s%N)
eval "
i=0
while $times
do
eval '$command' $silence
$pause
(( i++ ))
done
"
if $VERBOSE
then
echo
echo "duration: $[($(date +%s%N)-$timestamp)/1000000]ms"
fi

Expected result not return in shell script

I wrote the following code in shell script:
#!/bin/bash
tput clear
a=$(date +"%k")
if [ $a -lt 12 ]
then
echo "Hi!Good Morning"
fi
if [ $a -ge 12 -a $a -le 17 ]
then
echo "Hi!Good Afternoon"
fi
if [ $a -gt 17 -a $a -le 19 ]
then
echo "Hi!Good Evening"
fi
if [ $a -gt 19 -a $a -le 24 ]
then
echo "Hi!Good Night"
fi
while [ : ]
do
echo "BCSE!!\c"
read comm
set comm
case "$1" in
[""])
continue
;;
esac
case "$1" in
["editme"])
xdg-open "$2"&
;;
esac
case "$1" in
["newd"])
mkdir -p "$2"
;;
esac
case "$1" in
["mycontent"])
if [ -f "$2" ]
then
xdg-open "$2"&
else
echo "File doesn't exist"
fi
;;
esac
case "$1" in
["exitbcse"])
break
;;
esac
case "$1" in
[*])
echo "Wrong command!!";;
esac
done
The output should be :
Hi!Good morning
BCSE!!editme filename
now the file doesn't open instead I get
Hi!Good morning
BCSE!!editme filename
BCSE!!
Instead of:
while [ : ]
You may want to write:
while :
or
while true
while [ : ] may work, but not for the right cause, that sentence runs the command [, the command [ checks the expression you wrote inside, as it is a non-empty string it returns a true value (a zero), to ilustrate this, if you run while [ false ] you will also get an infinite loop.
And in the case control structures the options must be written without [] and "".
case "$1" in
exitbcse)
break
;;
esac
Edit:
Check this example with the corrections I described above and also other fixes:
#!/bin/bash
tput clear
a=$(date +"%k")
if [ $a -lt 12 ]
then
echo "Hi!Good Morning"
elif [ $a -ge 12 -a $a -le 17 ]
then
echo "Hi!Good Afternoon"
elif [ $a -gt 17 -a $a -le 19 ]
then
echo "Hi!Good Evening"
elif [ $a -gt 19 -a $a -le 24 ]
then
echo "Hi!Good Night"
fi
while true
do
echo "BCSE!!\c"
read comm option
case "$comm" in
"")
continue
;;
"editme")
xdg-open "$option"&
;;
"newd")
mkdir -p "$option"
;;
"mycontent")
if [ -f "$option" ]
then
xdg-open "$option"&
else
echo "File doesn't exist"
fi
;;
"exitbcse")
break
;;
*)
echo "Wrong command!!";;
esac
done

case statement not executing properly when the * option is included

i have a case script as follow :
for i in "$#"; do
arg=( $# )
case $i in
--string)
for ((i=0; i<${#arg[#]}; i++)) ; do
if [ "${arg[$i]}" == "--string" ] ; then
((i++))
STRING=${arg[$i]}
fi
done
;;
*)
print_help
exit
;;
esac
done
when i run ./test --some_command --string pattern ; it prints the help option.
When i run ./test --some_command --string pattern without the *) option in the string, it works.
Can you please tell me how to fix this.
Another example :
#!/bin/bash
test(){
echo i am testing this now
}
print_help()
{
echo help
}
for i in "$#"; do
arg=( $# )
case $i in
--string)
for ((i=0; i<${#arg[#]}; i++)) ; do
if [ "${arg[$i]}" == "--string" ] ; then
((i++))
STRING=${arg[$i]}
fi
done
echo $STRING
;;
--test)
test
;;
*)
print_help
exit
;;
esac
done
when i run ./test --string pattern --test. it prints
pattern
help
When the for loop gets to "pattern", it is not covered by a case branch so it hits the default branch and prints the help. You have to iterate over the arguments in a smarter way. Replace for for loop with
while (( $# > 0 )); do
arg=$1
shift
case $arg in
--string) STRING=$1; shift; echo "$STRING" ;;
--some-command) : ;;
--) break ;;
*) print_help; exit ;;
esac
done

comparing $var to

I have a test script the needs to read the variable 'LAB' and e-mail the correct company.
I've looked but can't find anything that has worked yet.
Any thoughts?
#!
#
LAB=3
#
if [ "$LAB" = "$1" ];then
echo "Got Zumbrota" && ./mailZ
fi
#
if [ "$LAB" = "$2" ];then
echo "Got Barron" && ./mailB
fi
#
if [ "$LAB" = "$3" ];then
echo "Got Stearns" && ./mailS
fi
If this a bash script, start your file with
#!/bin/bash
and use -eq for integer comparison and since LAB is an integer in your script
if [ $LAB -eq $1 ]
These cascading if statements can be condensed into a case statement:
case "$LAB" in
1) echo "Got Zumbrota" && ./mailZ
;;
2) echo "Got Barron" && ./mailB
;;
3) echo "Got Stearns" && ./mailS
;;
*) echo "don't know what to do with $LAB"
;;
esac

Resources