Advertisement
subbass

superfind

May 10th, 2024 (edited)
576
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 10.50 KB | Source Code | 0 0
  1. #!/bin/bash
  2. #
  3. # Script Name: superfind V4.1
  4. # Author: Subbass
  5. # Date: May 7, 2024
  6. # Pastebin: https://pastebin.com/84vhYa9a
  7. #
  8. # Description:
  9. #   A versatile file search tool that allows users to search for files based on patterns
  10. #   within user-defined paths stored in a configuration file or a specified directory.
  11. #   Supports creating playlists from the search results, editing the path configuration file,
  12. #   and displays results with colored output.
  13. #
  14. # Features:
  15. #   - Search within specified paths using flags or a direct folder path
  16. #   - Option to create a playlist of search results
  17. #   - Colored output for better readability
  18. #   - Ability to open and edit the path configuration file
  19. #
  20. # Usage:
  21. #   - Search for files using a flag:    ./superfind <flag> "search_pattern"
  22. #   - Search in a specified directory:  ./superfind -d <directory> "search_pattern"
  23. #   - Create a playlist of the results: ./superfind -p <flag> "search_pattern"
  24. #   - Edit the path configuration file: ./superfind --edit
  25. #   - Show help message:                ./superfind -h
  26. #
  27. # Examples:
  28. #   - superfind -m "old movie"      - Search for videos in movies directory.
  29. #   - superfind -d /tmp "test file" - Search in a specified directory.
  30. #   - superfind -p -m "funny clip"  - Create a playlist from search results.
  31. #   - superfind --edit              - Open the path configuration file in an editor.
  32. #
  33. # Configuration File: superfind_paths.conf
  34. #
  35.  
  36. # Extended Color Definitions
  37. col1="\033[0;31m"  # Red
  38. col2="\033[0;32m"  # Green
  39. col3="\033[0;33m"  # Yellow
  40. col4="\033[0;34m"  # Blue
  41. col5="\033[0;35m"  # Magenta
  42. col6="\033[0;36m"  # Cyan
  43. col7="\033[0;37m"  # Light Gray
  44. col8="\033[1;30m"  # Dark Gray
  45. col9="\033[1;31m"  # Light Red
  46. col10="\033[1;32m" # Light Green
  47. col11="\033[1;33m" # Light Yellow
  48. col12="\033[1;34m" # Light Blue
  49. col13="\033[1;35m" # Light Magenta
  50. col14="\033[1;36m" # Light Cyan
  51. col15="\033[1;37m" # White
  52.  
  53. # Text Style Definitions
  54. style_bold="\033[1m"
  55. style_underline="\033[4m"
  56. style_blink="\033[5m"
  57. style_reset="\033[0m"  # Reset color and style
  58.  
  59. # Color Usage in Output
  60. searchin_color="$col6"  # Use Cyan for "[ Searching in ]"
  61. file_color="$col2"      # Use Green for files
  62. folder_color="$col4"    # Use Blue for folders
  63. no_match="$col9"        # Use Light Red for no match
  64. reset_color="$style_reset"  # Reset color and style
  65.  
  66. # Determine the directory in which the script resides
  67. SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
  68.  
  69. # Configuration
  70. PATHS_FILE="$SCRIPT_DIR/superfind_paths.conf"
  71. EDITOR="${EDITOR:-nano}"
  72.  
  73. # Ensure the configuration file exists
  74. if [ ! -f "$PATHS_FILE" ]; then
  75.     # Default playlist directory using the user's home directory
  76.     default_playlist_dir="/home/$USER/Playlists"
  77.  
  78.     cat > "$PATHS_FILE" << EOF
  79. # Default Playlist Directory
  80. playlist_dir=$default_playlist_dir
  81.  
  82. # Example Paths Configuration
  83. # Use these examples as a guide to add your own:
  84. # -m /home/user/movies/
  85. # -mu /home/user/Music
  86. # --movies /home/user/movies/
  87. # -tvgroup /path/to/tv1;/path/to/tv2;/path/to/tv3
  88. #
  89. EOF
  90. fi
  91.  
  92. # Help function to include examples with wildcards
  93. show_help() {
  94.     echo "Usage: superfind [options] <search_pattern>"
  95.     echo "Options:"
  96.     echo "  -p, --playlist     Create a playlist of the results."
  97.     echo "  -d, --dir <dir>    Specify a directory for a one-time search."
  98.     echo "  -h, --help         Show this help message."
  99.     echo "  -e, --edit         Open the paths file in a text editor."
  100.     echo "  --copy             Copy matching files to the current directory."
  101.     echo "  --move             Move matching files to the current directory."
  102.     echo "  -o, --open         Open the created playlist."
  103.     echo "  <flag>             Search in the paths associated with this flag (e.g., -tvgroup for TV shows)."
  104.     echo "Examples:"
  105.     echo "  superfind --move -tvgroup '*episode*'  Search and move all files with 'episode' in their name under tvgroup paths."
  106.     echo " "
  107.     echo "User defined path flags:"
  108.     grep '^-' "$PATHS_FILE" | sed 's/^/  /'
  109. }
  110.  
  111. open_editor() {
  112.     $EDITOR "$PATHS_FILE"
  113. }
  114.  
  115. # Search function updated to accommodate wildcard patterns
  116. search_files() {
  117.     local search_pattern=$1
  118.     local pattern=$2
  119.     local search_flag=$3
  120.     local file_count=0
  121.     local folder_count=0
  122.     local cwd=$(pwd)
  123.  
  124.     local playlist_dir=$(grep 'playlist_dir=' "$PATHS_FILE" | cut -d'=' -f2)
  125.     if [[ -n "$playlist_dir" ]]; then
  126.         mkdir -p "$playlist_dir"
  127.     else
  128.         echo -e "${no_match}Error: Playlist directory not defined or invalid in configuration.${reset_color}"
  129.         return 1
  130.     fi
  131.  
  132.     local safe_search_term=$(echo "$pattern" | sed 's/[^a-zA-Z0-9]/_/g')
  133.     if [[ "$create_playlist" == true ]]; then
  134.         local playlist_file="${playlist_dir}/${search_flag}-${safe_search_term}-$(date +%Y%m%d%H%M%S).m3u"
  135.         > "$playlist_file"
  136.     fi
  137.  
  138.     IFS=';' read -ra paths <<< "$search_pattern"
  139.     for search_path in "${paths[@]}"; do
  140.         echo -e " [ Searching in ] ${searchin_color}$search_path${reset_color}"
  141.  
  142.         # Using find and grep to match complex patterns across paths
  143.         local file_results=$(find "$search_path" -type f -print | grep -i "$(echo "$pattern" | sed 's/\*/.*/g')")
  144.         if [[ -z "$file_results" ]]; then
  145.             do_nothing=0
  146.             #echo "   No files found matching pattern '$pattern' in $search_path."
  147.         else
  148.             if [[ "$create_playlist" == true ]]; then
  149.                 while IFS= read -r line; do
  150.                     local ext="${line##*.}"
  151.                     if [[ ! " ${exclude_list[@]} " =~ " $ext " ]]; then
  152.                         echo "$line" >> "$playlist_file"
  153.                         ((file_count++))
  154.                     fi
  155.                 done <<< "$file_results"
  156.                 # Sort the playlist after all files are added
  157.                 sort "$playlist_file" -o "$playlist_file"
  158.             else
  159.                 while IFS= read -r line; do
  160.                     echo -e "    ${line%/*}/${file_color}${line##*/}${reset_color}"
  161.                     ((file_count++))
  162.                     if [[ "$move_files" == true ]]; then
  163.                         local source_path=$(dirname "$line")
  164.                         local target_file="$(basename "$line")"
  165.                         if [[ "$source_path" == "$cwd" ]]; then
  166.                             echo "   File $line is already in the current directory, skipping move."
  167.                         elif [[ -f "$target_file" ]]; then
  168.                             echo "   Skipping move for $line: File already exists in target directory."
  169.                         else
  170.                             mv "$line" ./
  171.                             echo "   Moved $line to the current directory."
  172.                         fi
  173.                     fi
  174.  
  175.                     if [[ "$copy_files" == true ]]; then
  176.                         local source_path=$(dirname "$line")
  177.                         local target_file="$(basename "$line")"
  178.                         if [[ "$source_path" == "$cwd" ]]; then
  179.                             echo "   File $line is already in the current directory, skipping copy."
  180.                         elif [[ -f "$target_file" ]]; then
  181.                             echo "   Skipping copy for $line: File already exists in target directory."
  182.                         else
  183.                             cp "$line" ./
  184.                             echo "   Copied $line to the current directory."
  185.                         fi
  186.                     fi
  187.                 done <<< "$file_results"
  188.             fi
  189.             do_nothing=0
  190.             #echo "   ------------------------------------------"
  191.         fi
  192.  
  193.         local folder_results=$(find "$search_path" -type d -iname "*$pattern*" | grep -i "$(echo "$pattern" | sed 's/\*/.*/g')")
  194.         if [[ -z "$folder_results" ]]; then
  195.             do_nothing=0
  196.             #echo "   No folders found matching pattern '$pattern' in $search_path."
  197.         else
  198.             while IFS= read -r folder; do
  199.                 local num_files_in_folder=$(find "$folder" -type f -iname "*$pattern*" | wc -l)
  200.                 echo -e "   ${folder_color}$folder${reset_color} ($num_files_in_folder files)"
  201.                 ((folder_count++))
  202.             done <<< "$folder_results"
  203.         fi
  204.         do_nothing=0
  205.         #echo "   ------------------------------------------"
  206.     done
  207.  
  208.     if [[ "$create_playlist" == true ]]; then
  209.         echo "Playlist created: $playlist_file"
  210.     fi
  211.     echo "Results: ${file_count} files : ${folder_count} folders"
  212.  
  213.     # Open the playlist if the open flag is set
  214.     if [[ "$open_playlist" == true ]]; then
  215.         xdg-open "$playlist_file" &> /dev/null &
  216.         echo "Opening playlist..."
  217.     fi
  218. }
  219.  
  220. # Manual parsing of options
  221. create_playlist=false
  222. dir_path=""
  223. pattern=""
  224. flag=""
  225. open_playlist=false
  226. move_files=false
  227. copy_files=false  # Initialize the flag
  228.  
  229. # Updated command-line options parsing
  230. while [[ $# -gt 0 ]]; do
  231.     case "$1" in
  232.         -p|--playlist)
  233.             create_playlist=true
  234.             shift
  235.             ;;
  236.         -d|--dir)
  237.             dir_path="$2"
  238.             shift 2
  239.             ;;
  240.         -h|--help)
  241.             show_help
  242.             exit 0
  243.             ;;
  244.         -e|--edit)
  245.             open_editor
  246.             exit 0
  247.             ;;
  248.         --copy)
  249.             copy_files=true
  250.             shift
  251.             ;;
  252.         --move)
  253.             move_files=true
  254.             shift
  255.             ;;
  256.         -o|--open)
  257.             open_playlist=true
  258.             shift
  259.             ;;
  260.         -po)
  261.             create_playlist=true
  262.             open_playlist=true
  263.             shift
  264.             ;;
  265.         -*)
  266.             flag="$1"
  267.             pattern="$2"
  268.             shift 2
  269.             ;;
  270.         *)
  271.             pattern="$1"
  272.             shift
  273.             ;;
  274.     esac
  275. done
  276.  
  277. # Validate that a pattern is provided
  278. if [[ -z "$pattern" ]]; then
  279.     echo "Error: No search pattern provided."
  280.     show_help
  281.     exit 1
  282. fi
  283.  
  284. # Determine the search path based on flag or direct directory option
  285. if [[ -n "$dir_path" ]]; then
  286.     search_files "$dir_path" "$pattern"
  287. elif [[ -n "$flag" ]]; then
  288.     while IFS= read -r line; do
  289.         key=$(echo "$line" | cut -d' ' -f1)
  290.         path=$(echo "$line" | cut -d' ' -f2-)
  291.         if [[ "$flag" == "$key" ]]; then
  292.             search_files "$path" "$pattern" "$flag"
  293.             exit 0
  294.         fi
  295.     done < "$PATHS_FILE"
  296.     echo "Error: Flag $flag not found in $PATHS_FILE."
  297.     exit 1
  298. else
  299.     echo "Error: No valid directory or flag specified."
  300.     exit 1
  301. fi
  302.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement