Champlain Courses and Bash Lab - Snowboundport37/champlain GitHub Wiki

Champlain Courses and Bash Lab

This README includes what I did for the lab and the final working scripts.

Deliverable 1 explanations

1) xmlstarlet format --html --recover 2>/dev/null

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.

2) xmlstarlet select --template --copy-of "//html//body//div//div//table//tr"

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.

Deliverable 2 steps I used

Install tools

sudo apt-get update
sudo apt-get install xmlstarlet curl

Go to the working folder

cd ~/Downloads
ls

Make scripts executable

chmod +x Courses.bash assignment1.bash

Run the scraper

./Courses.bash

Verify courses.txt for the screenshot

head -n 10 courses.txt

Deliverable 3 steps I used

Run the menu script

./assignment1.bash

Test options

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

Final Courses.bash

#! /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/&amp;//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"

Final assignment1.bash

#! /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
⚠️ **GitHub.com Fallback** ⚠️