mirror of
https://github.com/bigbeartechworld/big-bear-scripts.git
synced 2026-03-31 06:24:02 -04:00
big-bear-interactive-rsync-with-file-sizes (#25)
* ✨ feat: Add interactive rsync script This commit introduces a new interactive rsync script that allows users to visually select specific files and directories for synchronization. The script provides the following features: - Interactive file/directory selection - Color-coded interface for better visibility - Multiple file selection support - Progress indication during transfer - Automatic destination directory creation - Input validation and error handling The script is designed to simplify the rsync process by eliminating the need for complex command-line arguments, making it more user-friendly and accessible for a wider audience. * ✨ feat: Add file size display and transfer confirmation This commit adds the following improvements to the interactive-rsync script: - Displays the file/directory size next to each item in the selection menu. - Adds a confirmation prompt before starting the transfer to ensure the user is ready. - Allows the user to specify file patterns to exclude from the transfer. - Displays a summary of the successful and failed transfers at the end of the process. These changes enhance the user experience by providing more information and control over the file transfer process.
This commit is contained in:
77
interactive-rsync/README.md
Normal file
77
interactive-rsync/README.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Big Bear Interactive Rsync
|
||||
|
||||
## Why?
|
||||
|
||||
This script provides an interactive way to select specific files and directories for rsync operations. Instead of syncing entire directories or writing complex rsync commands, you can visually select which items you want to sync.
|
||||
|
||||
## Features
|
||||
|
||||
- Interactive file/directory selection with size information
|
||||
- Color-coded interface for better visibility
|
||||
- Multiple file selection support
|
||||
- File/directory size display
|
||||
- Pattern-based file exclusion (e.g., _.tmp, _.log)
|
||||
- Transfer confirmation and progress tracking
|
||||
- Detailed transfer summary with success/failure reporting
|
||||
- Automatic destination directory creation
|
||||
- Input validation and error handling
|
||||
|
||||
## How to use?
|
||||
|
||||
1. Make the script executable:
|
||||
|
||||
```bash
|
||||
chmod +x run.sh
|
||||
```
|
||||
|
||||
2. Run the script (optionally with a source directory):
|
||||
|
||||
```bash
|
||||
./run.sh # Uses current directory as source
|
||||
./run.sh /path/to/directory # Uses specified directory as source
|
||||
```
|
||||
|
||||
3. Follow the interactive prompts:
|
||||
- Enter file patterns to exclude (optional)
|
||||
- Select items by entering their numbers (space-separated)
|
||||
- Type 'a' to select all items
|
||||
- Type 'q' to quit
|
||||
- Enter the destination path
|
||||
- Confirm the transfer
|
||||
|
||||
## Example
|
||||
|
||||
```bash
|
||||
./run.sh ~/Documents
|
||||
```
|
||||
|
||||
Example session:
|
||||
|
||||
```
|
||||
1) document.pdf (1.2M)
|
||||
2) images (2.3G)
|
||||
3) notes.txt (45K)
|
||||
|
||||
Enter file patterns to exclude: *.tmp *.log
|
||||
Enter numbers to select: 1 3
|
||||
Selected items: 2
|
||||
- document.pdf (1.2M)
|
||||
- notes.txt (45K)
|
||||
|
||||
Enter destination: ~/backup
|
||||
Start transfer? (y/n): y
|
||||
|
||||
Transfer Summary:
|
||||
Successfully transferred: 2/2
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
- Bash shell
|
||||
- rsync installed on your system
|
||||
|
||||
## One-line Installation
|
||||
|
||||
```bash
|
||||
bash -c "$(wget -qLO - https://raw.githubusercontent.com/bigbeartechworld/big-bear-scripts/master/interactive-rsync/run.sh)"
|
||||
```
|
||||
202
interactive-rsync/run.sh
Normal file
202
interactive-rsync/run.sh
Normal file
@@ -0,0 +1,202 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Function to print header
|
||||
print_header() {
|
||||
echo "================================================"
|
||||
echo "$1"
|
||||
echo "================================================"
|
||||
echo
|
||||
}
|
||||
|
||||
# Colors for better visibility
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Function to display menu
|
||||
show_menu() {
|
||||
clear
|
||||
print_header "Big Bear Interactive Rsync V0.0.1"
|
||||
|
||||
echo "Here are some links:"
|
||||
echo "https://community.bigbeartechworld.com"
|
||||
echo "https://github.com/BigBearTechWorld"
|
||||
echo ""
|
||||
echo "If you would like to support me, please consider buying me a tea:"
|
||||
echo "https://ko-fi.com/bigbeartechworld"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Function to get file size in human readable format
|
||||
get_size() {
|
||||
local size
|
||||
size=$(du -sh "$1" 2>/dev/null | cut -f1)
|
||||
echo "${size:-0B}"
|
||||
}
|
||||
|
||||
# Function to confirm action
|
||||
confirm_action() {
|
||||
local message="$1"
|
||||
local response
|
||||
|
||||
echo -e "\n${YELLOW}$message${NC} (y/n): "
|
||||
read -r response
|
||||
|
||||
case "$response" in
|
||||
[yY]|[yY][eE][sS]) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Set source directory to current directory if not provided
|
||||
SOURCE_DIR="${1:-.}"
|
||||
|
||||
# Check if source directory exists
|
||||
if [ ! -d "$SOURCE_DIR" ]; then
|
||||
show_menu
|
||||
echo -e "${RED}Error: Source directory '$SOURCE_DIR' does not exist${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to display numbered list of files/directories
|
||||
display_items() {
|
||||
local dir="$1"
|
||||
local i=1
|
||||
|
||||
show_menu
|
||||
echo -e "\n${GREEN}Available items in $dir:${NC}"
|
||||
echo "--------------------------------"
|
||||
|
||||
# Store items in an array
|
||||
items=()
|
||||
sizes=()
|
||||
while IFS= read -r item; do
|
||||
items+=("$item")
|
||||
sizes+=("$(get_size "$dir/$item")")
|
||||
echo -e "${YELLOW}$i)${NC} $item (${sizes[$((i-1))]})"
|
||||
((i++))
|
||||
done < <(ls -A "$dir")
|
||||
}
|
||||
|
||||
# Function to get selected items
|
||||
get_selections() {
|
||||
local selections=()
|
||||
local selection_sizes=()
|
||||
local done=false
|
||||
local exclude_pattern=""
|
||||
|
||||
# Ask for exclude pattern
|
||||
echo -e "\n${GREEN}Enter file patterns to exclude (e.g., '*.tmp *.log', or press Enter for none):${NC}"
|
||||
read -r exclude_pattern
|
||||
|
||||
while [ "$done" = false ]; do
|
||||
echo -e "\nEnter the numbers of items you want to sync (space-separated)"
|
||||
echo "Or press Enter when done, 'a' for all, 'q' to quit"
|
||||
read -r input
|
||||
|
||||
# Convert to lowercase
|
||||
input=$(echo "$input" | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
case "$input" in
|
||||
"q")
|
||||
show_menu
|
||||
echo "Quitting..."
|
||||
exit 0
|
||||
;;
|
||||
"a")
|
||||
echo "Selected all items"
|
||||
selections=("${items[@]}")
|
||||
selection_sizes=("${sizes[@]}")
|
||||
done=true
|
||||
;;
|
||||
"")
|
||||
if [ ${#selections[@]} -gt 0 ]; then
|
||||
done=true
|
||||
else
|
||||
echo -e "${RED}No items selected. Please select at least one item.${NC}"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
selections=()
|
||||
selection_sizes=()
|
||||
valid_selections=true
|
||||
for num in $input; do
|
||||
if [[ "$num" =~ ^[0-9]+$ ]] && [ "$num" -ge 1 ] && [ "$num" -le ${#items[@]} ]; then
|
||||
selections+=("${items[$((num-1))]}")
|
||||
selection_sizes+=("${sizes[$((num-1))]}")
|
||||
else
|
||||
echo -e "${RED}Invalid selection: $num${NC}"
|
||||
valid_selections=false
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "$valid_selections" = true ]; then
|
||||
done=true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
show_menu
|
||||
echo -e "\n${GREEN}Selected items:${NC}"
|
||||
local total_count=${#selections[@]}
|
||||
echo -e "${YELLOW}Total files/directories: $total_count${NC}"
|
||||
|
||||
for i in "${!selections[@]}"; do
|
||||
echo "${selections[$i]} (${selection_sizes[$i]})"
|
||||
done
|
||||
|
||||
# Ask for destination
|
||||
echo -e "\n${GREEN}Enter destination path:${NC}"
|
||||
read -r destination
|
||||
|
||||
# Validate destination
|
||||
if [ -z "$destination" ]; then
|
||||
echo -e "${RED}Error: Destination cannot be empty${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create destination if it doesn't exist
|
||||
mkdir -p "$destination"
|
||||
|
||||
# Confirm transfer
|
||||
if ! confirm_action "Start transfer of $total_count items to $destination?"; then
|
||||
echo -e "${YELLOW}Transfer cancelled${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Prepare rsync exclude options
|
||||
local exclude_opts=""
|
||||
if [ -n "$exclude_pattern" ]; then
|
||||
for pattern in $exclude_pattern; do
|
||||
exclude_opts="$exclude_opts --exclude='$pattern'"
|
||||
done
|
||||
fi
|
||||
|
||||
# Perform rsync for each selected item
|
||||
local success_count=0
|
||||
local failed_items=()
|
||||
|
||||
for item in "${selections[@]}"; do
|
||||
echo -e "\n${GREEN}Syncing: $item${NC}"
|
||||
if eval rsync -av --info=progress2 $exclude_opts \""$SOURCE_DIR/$item"\" \""$destination/"\"; then
|
||||
((success_count++))
|
||||
else
|
||||
failed_items+=("$item")
|
||||
fi
|
||||
done
|
||||
|
||||
# Show summary
|
||||
echo -e "\n${GREEN}Transfer Summary:${NC}"
|
||||
echo -e "Successfully transferred: $success_count/$total_count"
|
||||
|
||||
if [ ${#failed_items[@]} -gt 0 ]; then
|
||||
echo -e "\n${RED}Failed transfers:${NC}"
|
||||
printf '%s\n' "${failed_items[@]}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
display_items "$SOURCE_DIR"
|
||||
get_selections
|
||||
Reference in New Issue
Block a user