Champlain Courses and Bash Lab - Snowboundport37/champlain GitHub Wiki
This README includes what I did for the lab and the final working scripts.
This command cleans and reformats HTML so it is easier to process.
The --html option tells xmlstarlet to treat the input as HTML.
The --recover option attempts to fix broken or messy HTML.
The 2>/dev/null part hides error messages so they do not clutter the terminal output.
This command uses XPath to select table rows from the HTML.
The --template option allows structured output formatting.
The --copy-of option prints the entire matching node including tags and contents.
copy of vs value of
--copy-of outputs the full element with tags.
--value-of outputs only the text inside the element without tags.
sudo apt-get update
sudo apt-get install xmlstarlet curl
cd ~/Downloads
ls
chmod +x Courses.bash assignment1.bash
./Courses.bash
head -n 10 courses.txt
./assignment1.bash
Option 1
Enter an instructor name exactly as shown in courses.txt
Option 2
Confirm instructor counts display
Option 3
Enter a location such as GBTC 114 or JOYC 302
Option 4
Enter a course prefix such as ACC, ANM, or SEC
Option 5
Exit
#! /bin/bash
# Use local HTML file from the lab download
link="Courses-1.html"
# Read HTML file
fullPage=$(cat "$link")
# Remove DOCTYPE line to reduce external DTD warnings
cleanHtml=$(echo "$fullPage" | sed '/<!DOCTYPE/d')
# Extract all table rows
toolOutput=$(echo "$cleanHtml" | \
xmlstarlet fo --html --recover 2>/dev/null | \
xmlstarlet sel --template --copy-of "//table//tr")
# Convert HTML rows into semicolon separated lines
echo "$toolOutput" | \
sed 's/<\/tr>/\n/g' | \
sed -e 's/&//g' | \
sed -e 's/<tr>//g' | \
sed -e 's/<td[^>]*>//g' | \
sed -e 's/<\/td>/;/g' | \
sed -e 's/<[/\]\{0,1\}a[^>]*>//g' | \
sed -e 's/<[/\]\{0,1\}nobr>//g' \
> courses.txt
echo "Done. Output saved to courses.txt"
#! /bin/bash
clear
# Generate courses.txt each time the menu runs
bash Courses.bash
courseFile="courses.txt"
function displayCoursesofInst(){
echo -n "Please Input an Instructor Full Name: "
read instName
echo ""
echo "Courses of $instName :"
cat "$courseFile" | grep "$instName" | cut -d';' -f1,2 | \
sed 's/;/ | /g'
echo ""
}
function courseCountofInsts(){
echo ""
echo "Course Instructor Distribution"
cat "$courseFile" | cut -d';' -f7 | \
grep -v "/" | grep -v "\.\.\." | \
sort -n | uniq -c | sort -n -r
echo ""
}
# Display courses at a given location
# Output number, title, days, time, instructor
function displayCoursesAtLocation(){
echo -n "Enter location (for example JOYC 302): "
read loc
echo ""
echo "Courses at location $loc:"
awk -F";" -v L="$loc" '
NR > 1 && $10 == L {
printf "%s | %s | %s | %s | %s\n", $1, $2, $5, $6, $7
}
' "$courseFile"
echo ""
}
# Display courses with available seats for a given course prefix
function displayAvailableCourses(){
echo -n "Enter course code prefix (for example ACC or ANM): "
read code
echo ""
echo "Courses with available seats for code prefix $code:"
awk -F";" -v C="$code" '
NR > 1 && $1 ~ C && $4 > 0 {
printf "%s | %s | %s | %s | %s | Seats: %s\n", \
$1, $2, $5, $6, $7, $4
}
' "$courseFile"
echo ""
}
while :
do
echo ""
echo "Please select an option:"
echo "[1] Display courses of an instructor"
echo "[2] Display course count of instructors"
echo "[3] Display courses at a given location"
echo "[4] Display courses with available seats for a course code"
echo "[5] Exit"
read userInput
echo ""
if [[ "$userInput" == "1" ]]; then
displayCoursesofInst
elif [[ "$userInput" == "2" ]]; then
courseCountofInsts
elif [[ "$userInput" == "3" ]]; then
displayCoursesAtLocation
elif [[ "$userInput" == "4" ]]; then
displayAvailableCourses
elif [[ "$userInput" == "5" ]]; then
echo "Goodbye"
break
else
echo "Invalid option. Please try again."
fi
done