Created
May 29, 2024 10:11
Revisions
-
hunandy14 created this gist
May 29, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,229 @@ #!/bin/bash # This script displays the directory tree structure, color-codes files and folders, # and optionally shows file sizes and hidden files. # Usage: # tree.sh [-a] [-s] <directory> # -a Show all files including hidden files # -s Show file sizes # Detailed Usage: # - `-a` or `--all`: Show all files, including hidden files. # - `-s` or `--size`: Display the size of each file. # Examples: # 1. Show the directory structure, including hidden files and file sizes: # tree.sh -a -s testdir/ # # 2. Show the directory structure without hidden files and file sizes: # tree.sh testdir/ # # 3. Show the directory structure with file sizes but without hidden files: # tree.sh -s testdir/ # Function to format file size function format_size() { local size=$1 local units=("B" "KB" "MB" "GB" "TB" "PB") local unit_index=0 local decimal_places=3 while (( $(echo "$size >= 1024" | bc -l) )); do size=$(echo "scale=$decimal_places; $size / 1024" | bc) unit_index=$(( unit_index + 1 )) done size=$(echo $size | awk '{printf "%.'$decimal_places'f", $0}') size=$(echo $size | sed 's/\.0*$//;s/\.\([0-9]*[1-9]\)0*$/.\1/') echo "$size ${units[$unit_index]}" } # Function to print the item name with color based on file type function print_item() { local item_name=$1 shift local description="" local item_type="" while [ $# -gt 0 ]; do case $1 in --description=*|-d) if [[ "$1" == "--description="* ]]; then description="${1#*=}" shift else description="$2" shift 2 fi ;; --type=*|-t) if [[ "$1" == "--type="* ]]; then item_type="${1#*=}" shift else item_type="$2" shift 2 fi ;; *) echo "Unknown argument: $1" return 1 ;; esac done local base_name=$(basename "$item_name") local extension="${base_name##*.}" local COLOR_RESET="\033[0m" local COLOR_FOLDER="\033[1;34m" # Blue color for folders local COLOR_EXEC="\033[1;32m" # Green color for executable files local COLOR_LINK="\033[1;36m" # Cyan color for links local COLOR_COMPRESSED="\033[1;31m" # Red color for compressed files local COLOR_IMAGE="\033[1;35m" # Magenta color for image files local COLOR_VIDEO="\033[1;33m" # Yellow color for video files local COLOR_AUDIO="\033[1;36m" # Cyan color for audio files local COLOR_FIFO="\033[1;33;40m" # Yellow background black text for FIFO local COLOR_DEVICE="\033[1;34;43m" # Yellow background blue text for devices local COLOR_SUID="\033[1;37;41m" # White background red text for SUID files local COLOR_SGID="\033[1;30;43m" # Black background yellow text for SGID files local COLOR_STICKY="\033[1;37;44m" # Blue background white text for sticky directories local COLOR_OW="\033[1;30;42m" # Green background black text for other-writable directories local COLOR_DEFAULT="\033[0m" # Default color for other files local colored_name if [ "$item_type" = "folder" ]; then colored_name="${COLOR_FOLDER}${base_name}/${COLOR_RESET}" else if [ -x "$item_name" ]; then colored_name="${COLOR_EXEC}${base_name}${COLOR_RESET}" elif [ -L "$item_name" ]; then colored_name="${COLOR_LINK}${base_name}${COLOR_RESET}" elif [[ "$extension" =~ ^(zip|tar|gz|bz2|xz|7z|rar)$ ]]; then colored_name="${COLOR_COMPRESSED}${base_name}${COLOR_RESET}" elif [[ "$extension" =~ ^(jpg|jpeg|png|gif|bmp|tiff|svg|ico)$ ]]; then colored_name="${COLOR_IMAGE}${base_name}${COLOR_RESET}" elif [[ "$extension" =~ ^(mp4|mkv|avi|mov|flv|wmv|webm)$ ]]; then colored_name="${COLOR_VIDEO}${base_name}${COLOR_RESET}" elif [[ "$extension" =~ ^(mp3|wav|ogg|flac|aac|m4a)$ ]]; then colored_name="${COLOR_AUDIO}${base_name}${COLOR_RESET}" elif [ -p "$item_name" ]; then colored_name="${COLOR_FIFO}${base_name}${COLOR_RESET}" elif [ -b "$item_name" ] || [ -c "$item_name" ]; then colored_name="${COLOR_DEVICE}${base_name}${COLOR_RESET}" elif [ -u "$item_name" ]; then colored_name="${COLOR_SUID}${base_name}${COLOR_RESET}" elif [ -g "$item_name" ]; then colored_name="${COLOR_SGID}${base_name}${COLOR_RESET}" elif [ -k "$item_name" ]; then colored_name="${COLOR_STICKY}${base_name}${COLOR_RESET}" elif [ -w "$item_name" ] && [ -d "$item_name" ]; then colored_name="${COLOR_OW}${base_name}${COLOR_RESET}" else colored_name="${COLOR_DEFAULT}${base_name}${COLOR_RESET}" fi fi if [ -n "$description" ]; then echo -e "${colored_name} ${description}" else echo -e "${colored_name}" fi } # Function to recursively print the directory tree structure function print_tree() { local directory=$1 local prefix=$2 local files=() if $show_hidden; then files=("$directory"/{.,}*) else files=("$directory"/*) fi # Filter out non-existent files and directories (handle empty directories) files=(${files[@]/*\*/}) local last_index=$((${#files[@]} - 1)) for i in "${!files[@]}"; do local file="${files[$i]}" local basename=$(basename "$file") local new_prefix="$prefix" if [ "$basename" == "." ] || [ "$basename" == ".." ]; then continue fi if [ $i -eq $last_index ]; then echo -n "${prefix}└── " new_prefix="$prefix " else echo -n "${prefix}├── " new_prefix="$prefix│ " fi if [ -d "$file" ]; then dir_count=$((dir_count + 1)) print_item "$file" -t "folder" print_tree "$file" "$new_prefix" else if $show_size; then local size=$(stat -c %s "$file") local formatted_size=$(format_size $size) print_item "$file" -d "($formatted_size)" -t "file" else print_item "$file" -t "file" fi file_count=$((file_count + 1)) fi done } # Default options show_hidden=false show_size=false dir_count=0 file_count=0 # Parse options while getopts "as" opt; do case $opt in a) show_hidden=true ;; s) show_size=true ;; *) echo "Usage: $0 [-a] [-s] <directory>" echo " -a Show all files including hidden files" echo " -s Show file sizes" exit 1 ;; esac done shift $((OPTIND - 1)) # Check if a directory is provided as an argument if [ -z "$1" ]; then echo "Usage: $0 [-a] [-s] <directory>" echo " -a Show all files including hidden files" echo " -s Show file sizes" exit 1 fi # Remove trailing slash from the directory if it exists directory=$(echo "$1" | sed 's:/*$::') # Print the initial directory with color print_item "$directory" -t "folder" print_tree "$directory" "" # Print the summary echo -e "\n$dir_count directories, $file_count files"