Reputation: 37
i am doing up a program that if the user enter a number,(that number refer to item quantity being sold). The programme will then automatically update the available quantity and sold quantity and reflect back to user.
I would also like to know if there is a way to prevent user enter a integer that is bigger that the int store in "$avilable" variable
Thank you
The output will be as shown below.
Title : Star Wars VI – Return of the Jedi
Author : Darth Vader
No. of copies sold : 3
Current book info :
Star Wars VI – Return of the Jedi, Darth Vader, $8.05, 30, 20
New book info :
Star Wars VI – Return of the Jedi, Darth Vader, $8.05, 27, 23
Below is my code, however i am facing difficulty as it is not working.
{
echo -n "Title: "
read title
echo -n "Author: "
read author
echo -n "No. of copies sold: "
read numsold
if [[ ! $numsold|| $numsold = *[^0-9]* ]]; then
echo "Please input a number." >&2
fi
newavilable=$((avilable - numsold))
newsold=$((sold + numsold))
sed "s/${sold}/${newsold}/g" BookDB.txt > BookDB1.txt
mv -f BookDB1.txt BookDB.txt
sed "s/${avilable}/${newavilable}/g" BookDB.txt > BookDB1.txt
mv -f BookDB1.txt BookDB.txt
echo $title:$author:$price:$avilable:$sold >> BookDB.txt
}
Upvotes: 2
Views: 410
Reputation: 9124
I would proceed like this:
#!/bin/bash
info=""
# while $info is not set
while [[ -z "$info" ]] ; do
# Get at title
title=""
while [[ -z "$title" ]] ; do
echo -n "Title: "
read title
done
# Get an author
author=""
while [[ -z "$author" ]] ; do
echo -n "Author: "
read author
done
# Check book is in DB
info=$(grep "^${title}:${author}:" BookDB.txt)
if [[ -z "$info" ]] ; then
echo "Not in database."
fi
done
# Extract number of books available/already sold
avilable="$(cut -d: -f4 <<< $info)"
sold="$(cut -d: -f5 <<< $info)"
# Get number of recently sold books
while [[ -z "$numsold" ]] ; do
# We want a number…
while [[ ! "$numsold" =~ ^[0-9]{1,}$ ]] ; do
echo -n "No. of copies sold: "
read numsold
done
newavilable=$((avilable - numsold))
newsold=$((sold + numsold))
# And we want it lower than $newavilable
if [[ $newavilable -lt 0 ]] ; then
echo "Too high"
numsold=""
fi
done
# Print old info
echo "Current book info:"
echo "$info"
# Currently prints desired new DB
echo "New book info:"
# Add '-i' option to sed to edit BookDB.txt in place instead of printing it
sed -e "s/^\(${title}:${author}:[0-9]\+\):${avilable}:${sold}$/\1:${newavilable}:${newsold}/" \
BookDB.txt
In bash tests, don't forget to surround your variables with double quotes, or you'll have bad surprises when they are empty.
Edit: If your price is a float instead of an integer, you can extract it with:
price="$(cut -d: -f3 <<< $info)"
and replace final sed
command by either
sed -e "s/^\(${title}:${author}:${price}\):${avilable}:${sold}$/\1:${newavilable}:${newsold}/" BookDB.txt
# extracted value ^^^^^^^^
or
sed -e "s/^\(${title}:${author}:[0-9.]\+\):${avilable}:${sold}$/\1:${newavilable}:${newsold}/" BookDB.txt
# added a dot ^
As bash does not handle floats, use something like bc
(or dc
, or perl/python/…) to perform operations, e.g. something like:
totalprice=$(echo "$unitprice * $numsold" | bc)
Upvotes: 1