How to update book title? - linux

ok.. i'm having trouble with updating new book title.. i've already searched for solutions on this website.. and ive tried them but none of them work..
function update_book
{
#echo "Title: "
read -p $'Title: ' updatetitle
#echo "Author: "
read -p $'Name: ' updatename
if grep -Fq "${updatetitle}:${updatename}" BookDB.txt
then
echo "Book found!"
if ! [ -f BookDB.txt ] ; then
touch BookDB.txt
fi
selection=0
until [ "$selection" = "f" ]; do
echo ""
echo ""
echo "Book Update System"
echo ""
echo ""
echo "a) Update title"
echo "b) Update Author"
echo "c) Update Price"
echo "d) Update Qty Available"
echo "e) Update Qty Sold"
echo "f) Back to main menu"
echo -n "Enter your option: "
read selection
echo ""
case $selection in
a) upd_title;press_enter;;
b) upd_author;press_enter;;
c) upd_price;press_enter;;
d) upd_qty_avail;press_enter;;
e) upd_qty_sold;press_enter;;
f) main_menu;press_enter;;
* ) tput setf 4;echo "Please enter a, b, c, d, e, or f";tput setf 7; press_enter
esac
done
else
echo "Error!! Book does not exist!" #not found
fi
}
ok i've made some changes to the codes for this function.. found out that i should use awk to update from old to new. and use grep to get line number..so it's best i stick with this..
function upd_title
{
read -p 'New title: ' title
#awk '/liine/{ print NR; exit }' BookDB.txt
grep -n 'regex' | sed 's/^\([0-9]\+\):.*$/\1/'
awk 'NR==n{$1=a}1' FS=":" OFS =":" n=$linenumber a = $title BookDB.txt
echo "New title successfully updated!!"
}
but after i tried that code.. this is what i got:
Advanced Book Inventory System
1) Add new book
2) Remove existing book info
3) Update book info and quantity
4) Search for book by title/author
5) Process a book sold
6) Inventory summary report
7) Quit
Enter your option: 3
Title: The Notebook
Name: Nicholas Sparks
Book found!
Book Update System
a) Update title
b) Update Author
c) Update Price
d) Update Qty Available
e) Update Qty Sold
f) Back to main menu
Enter your option: a
New title: Notebook
still doesn't update the title.. >.< anyone can help me point out what's the problem? am i missing something here
help me how to do this.. thanks! :D :D

$updatetitle and $updateauthor defined by the read statements in update_book() are not visible in the upd_title() and other functions you define.
Try exporting them after they are read in. If this doesn't work, pass them in as positional parameters to update_title():
upd_title $update_title $update_author
...
function upd_title
{
update_title=$1
update_author=$2
...
}

Related

Assign variable separated by comma based on user input using function

I wanted to assign variable name separated by comma based on user input using function.
I will get the user input using below script and it will call function for variable assignment
while [ "$ans" != "q" ]
do
clear
echo "Choose your subject"
echo "Press q once done"
echo " 1.Science"
echo " 2.Maths"
echo " 3.English"
...
read ans
case $ans in
1) clear
Science;;
2) clear
Maths;;
3) clear
English;;
....
esac
done
clear
subjects=""
Science()
{
subjects+="$subjects Science"
}
Maths()
{
subjects+="$subjects Maths"
}
English()
{
subjects+="$subjects English"
}
At the end I wanted to have variable subjects to have option choose by the user:
Etc:
Science,Maths
Maths,English
Science,English
English
In bash, the function definition must be placed before any calls to the function.
The line subjects="" must be placed before the while loop. Otherwise its value will get lost (will be set to empty string) on exit from the loop.
The += operator causes double concatenation in the line subjects+="$subjects Science", since the right hand side contains already the expansion of the subjects variable. Either subjects="$subjects Science", or subjects+=" Science" must have been used (the same is also true for other lines in which the += operator is used). Besides, since a comma separated list is desired, a , character must be used while concatenating strings instead of space character. For example: subjects="$subjects,Science"
So a corrected script could be like this:
#!/bin/bash
subjects=""
Science() {
subjects="$subjects,Science"
}
Maths() {
subjects="$subjects,Maths"
}
English() {
subjects="$subjects,English"
}
while [ "$ans" != "q" ]; do
clear
echo "Choose your subject"
echo "Press q once done"
echo " 1.Science"
echo " 2.Maths"
echo " 3.English"
read -r ans
case $ans in
1) Science;;
2) Maths;;
3) English;;
esac
done
subjects=${subjects:1} # to remove the leading ',' character
echo "Your selections are $subjects"
Note: I wouldn't normally use a function just to append a simple string to a variable.

Bash kdialog Input Box Not Clossing? Possible bad return from msgbox

I am coding in bash ,using Ubuntu 18.04, and I am playing around with kdialog. I made a simple magic eight ball themed program and I am unable to close the input box and exit the program, instead I get stuck in a loop. This code was originally made in BASH dialog and I decided to change it to kdialog. Any help would be greatly appreciated. It is something simple that I am overlooking.
#!/bin/bash
#version 3
OUTPUT="TEMP.txt"
>$OUTPUT
while [ true ]
do
shuffle() {
local i tmp size max rand
size=${#array[*]}
max=$(( 32768 / size * size ))
for ((i=size-1; i>0; i--));
do
while (( (rand=$RANDOM) >= max ));
do :;
done
rand=$(( rand % (i+1) ))
tmp=${array[i]}
array[i]=${array[rand]}
array[rand]=$tmp
done
}
array=( 'It Is Certain'
'Without A Doubt'
'Maybe'
'Signs Point To Yes'
'Most Likely'
'As I See It, Yes'
'Ask Again Later'
'Concentrate And Ask Again'
'HAHAH No..'
'Ask Again'
'Have Faith In Yourself'
'Very Doubtful'
'Outlook Not So Good'
'My Sources Say No'
'Unknown At This Time'
'Could Happen Any Moment Now'
'Is That A Joke?'
'Unlikely' )
shuffle
function sayhello(){
local n=${array[#]}-""
#display it
kdialog --msgbox "This Is What I See: ${array}"
#--clear --msgbox "${array}" 8 41
}
# show an inputbox
kdialog --title "Welcome " \
--inputbox "Ask and you shall recieve great fortune: " #8 60
function think_tank(){
progress=$(kdialog --progressbar "hmmm Let Me Think..." 4);
sleep 1;
qdbus $progress Set "" value 1 > /dev/null;
sleep 1;
qdbus $progress Set "" value 2 > /dev/null;
sleep 1;
qdbus $progress Set "" value 3 > /dev/null;
sleep 1;
qdbus $progress Set "" value 4 > /dev/null;
sleep 1;
qdbus $progress close > /dev/null;
sleep 1
#kdialog --title "This is a passive popup" --passivepopup \
#"It will disappear in about 10 seconds" 10
}
# get response
response=$?
# get data stored in $OUPUT using input redirection
name=$(<$OUTPUT)
case $response in
0)
think_tank
sayhello ${array[#]}
;;
1)
echo "Goodbye For Now."
exit 0
;;
255)
echo "Goodbye For Now."
exit 0
;;
esac
#rm $OUTPUT
done
done
After some sleep I easily figured this issue out. I removed the case statement and used if statements instead. The program would not break out of the case statement due to a return 0 from kdialog's --msgbox.
#made some quick msgbox functions
if [ "$?" = 0 ];
then
think_tank #progress bar
msg_box #results
elif [ "$?" = 1 ];
then
goodbye #closing message box
exit 0;
else
error #error message box
exit 0;
fi;

Bash script looping after end of file

My bash script asks user for their first name, last name, address and phone number and writes this information that is input by the user to a file of the format "firstname.lastname"; however I want to repeat this a number of times (I actually wanted to do something like a do..while loop where it runs atleast one time and asks user if they want to continue creating accounts or not but I see there is no do...while for bash it seems). So when I execute this bash script in the terminal it will ask for how many accounts to be made and I provide all the input but the it only runs one time. What am I doing wrong? Here is my script.
#!bin/bash
echo "How many accounts are you creating?"
read num
echo "Enter first name"
read fName
echo "Enter last name"
read lName
echo "Enter address"
read add
echo "Enter phone number"
read phn
echo "Enter gender m for male and f for female"
read gender
if [ "$gender" == "m" ]
then
sex="male"
elif [ "$gender" == "f" ]
then
sex="female"
else
echo"Invalid gender. Restart the script and enter a valid gender"
exit 0
fi
for (( i = 0; i<=num; i++))
do
cat > $fName.$lName <<-EOF
Full Name: $fName $lName
Address: $add
Phone number: $phn
Gender: $gender
EOF
done
zerobandwidth's answer is correct, but as an alternative answer, it is in fact quite easy to do what you initially wanted to do:
while true; do
# Your account creation code goes here
echo "Create another account (y/n)?"
read another
if [ "$another" != y ]; then
break
fi
done
Put your input code inside the loop, or wrap that code in a function and call the function inside the loop.

shell scripting - assigning one variable to another - arrays

I have a doubt. When i declare a value and assign to some variable, I don't know how to reassign the same value to another variable. See the code snippet below.
Here is my actual script.
#!/bin/sh
a=AA
b=BB
c=CC
d=DD
e=EE
f=FF
alpha_array=(a b c d e f)
process_array=(proc1 proc2 proc3 proc4)
array_1=("")
array_2=("")
display_array() {
echo "array1 = ${array_1[#]}"
echo "array2 = ${array_2[#]}"
}
checkarg() {
if [[ " ${alpha_array[*]} " == *" $token "* ]]; then
echo "alphabet contains $token "
array_1=("${array_1[#]}" "$token")
$token=${$token}
echo "TOKEN = $token"
elif [[ " ${process_array[*]} " == *" $token "* ]]; then
echo "process contains $token "
array_2=("${array_2[#]}" "$token")
else
echo "no matches found"
display_array
exit 1
fi
}
for token in $#
do
echo $token
checkarg
done
display_array
Here the below two lines
$token=${$token}
echo "TOKEN = $token"
should display my output as
TOKEN = AA
TOKEN = BB
when i run my script with the following arguments.
./build.sh a b proc1
Kindly help me out on those 2 lines.
It sounds like what you want is variable indirection. There's a lot of code in your question which has nothing to do with that, but let me try to distill it down to what I understand as the important parts:
a=AA
b=BB
alpha_array=(a b)
for token in "${alpha_array[#]}"; do
value=${!token}
echo "value of variable $token is $value"
done
When run, this will output:
value of variable a is AA
value of variable b is BB
For more details, see BashFAQ #6.
By the way, this can often be replaced with use of associative arrays, in which case you might write:
declare -A tokens=( [a]=AA [b]=BB )
for token in "${!tokens[#]}"; do
value=${tokens[$token]}
echo "value of token $token is $value"
done
This has the advantage that your key/value pairs are all stored inside the array -- there's no potential for collision with other variable names.

Check user input against words in text file

I am working on an option for my program and it should work like this:
user inputs title
user inputs author
system then checks user's title & author input in the text file named BookDB.txt
if there is already existing record in the text file, system will prompt an error
else it will continue user to input price, quantity available and quantity sold.
book will then be added
I tried playing around with grep but to no avail.
Below are my codes for this particular function.
function fnAddBook()
{
echo "Title: "
read inputTitle
echo "Author: "
read inputAuthor
if grep -Fq "$inputTitle" BookDB.txt; then
if grep -Fq "$inputAuthor" BookDB.txt; then
echo "Error!"
fi
else
echo "Price: "
read inputPrice
echo "$inputTitle:$inputAuthor:$inputPrice" >> BookDB.txt
echo "New Book successfully added!"
fi
}
contents of BookDB.txt
format of the contents | Title:Author:Price:QtyAvail:QtySold
Hello World:Andre:10.50:10:5
Three Little Pig:Andrew Lim:89.10:290:189
All About Ubuntu:Ubuntu Team:76.00:55:133
Catch Me If You Can:Mary Ann:23.60:6:2
Happy Day:Mary Ann:12.99:197:101
UPDATED PROBLEM:
In this case, even if I typed "Catch Me If You Can" as title + "Ubuntu Team" as Author, it raises the error. How can I modify the codes such that it checks line by line?
Thanks in advance to those who helped! :)
There are 3 problems with your code.
The first is that the x option to grep causes it to match only complete lines, and since you put author and title on the same line, this will not match.
With the x option "Gaiman" does not match "Gaiman:Nation:$20", if you remove the x from the grep-options, this will work.
The second problem is that the two greps are independent of eachother. Thus if you have a book titled 'Nation' and a book by 'Gaiman' it will be considered a match, even if the 'Nation' book you have is 'The wealth of Nations' and the Gaiman book you've got is 'Anansi Boys'.
The third problem is that grep will find partial matches. If you try to enter the book "It", then grep will conclude it's already in the database, because "It came from the desert" is.
You need a sentinel-value to delineate the titles to fix this. (the sentinel must be some character that cannot exist in book-titles or author-names)
function fnAddBook()
{
echo "Title: "
read inputTitle
echo "Author: "
read inputAuthor
if grep -Fq "$inputTitle:inputAuthor:" BookDB.txt
then
echo "Error!"
else
echo "Price: "
read inputPrice
echo "$inputTitle:$inputAuthor:$inputPrice" >> BookDB.txt
echo "New Book successfully added!"
fi
}
This assumes that ':' cannot occur in authornames or booknames.

Resources