Skip to content

Instantly share code, notes, and snippets.

@yelban
Created November 10, 2024 06:11
Show Gist options
  • Save yelban/feaaa175020bb0c4ce936a931e1703d3 to your computer and use it in GitHub Desktop.
Save yelban/feaaa175020bb0c4ce936a931e1703d3 to your computer and use it in GitHub Desktop.

Revisions

  1. yelban created this gist Nov 10, 2024.
    169 changes: 169 additions & 0 deletions ss.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,169 @@
    #!/bin/bash

    # 顯示使用說明
    usage() {
    echo "使用方法: $0 [-d 目錄] [-i] [-e 排除目錄] 搜尋字串"
    echo "選項:"
    echo " -d 指定搜尋目錄 (預設: 當前目錄)"
    echo " -i 忽略大小寫"
    echo " -e 額外排除的目錄 (用逗號分隔)"
    echo " -a 顯示所有目錄 (不使用預設排除清單)"
    echo ""
    echo "預設排除的目錄:"
    echo " node_modules, .git, .next, dist, build, .cache,"
    echo " .terraform, coverage, .DS_Store, .idea, .vscode,"
    echo " __pycache__, vendor, tmp"
    echo ""
    echo "範例:"
    echo " $0 \"搜尋文字\" # 基本搜尋"
    echo " $0 -d /path/to/dir \"搜尋文字\" # 指定目錄"
    echo " $0 -i \"搜尋文字\" # 忽略大小寫"
    echo " $0 -e \"logs,temp\" \"搜尋文字\" # 額外排除目錄"
    echo " $0 -a \"搜尋文字\" # 搜尋所有目錄"
    exit 1
    }

    # 預設排除的目錄清單
    DEFAULT_EXCLUDES=(
    "node_modules"
    ".git"
    ".next"
    "dist"
    "build"
    ".cache"
    ".terraform"
    "coverage"
    ".DS_Store"
    ".idea"
    ".vscode"
    "__pycache__"
    "vendor"
    "tmp"
    ".npm"
    "logs"
    )

    # 初始化變數
    SEARCH_DIR="."
    IGNORE_CASE=""
    EXCLUDE_DIRS=""
    USE_DEFAULT_EXCLUDES=true

    # 處理命令列參數
    while getopts "d:ie:ah" opt; do
    case $opt in
    d) SEARCH_DIR="$OPTARG" ;;
    i) IGNORE_CASE="-i" ;;
    e) EXCLUDE_DIRS="$OPTARG" ;;
    a) USE_DEFAULT_EXCLUDES=false ;;
    h) usage ;;
    ?) usage ;;
    esac
    done

    # 移除已處理的選項,剩下的是搜尋字串
    shift $((OPTIND-1))

    # 檢查是否提供搜尋字串
    if [ $# -eq 0 ]; then
    echo "錯誤: 請提供搜尋字串"
    usage
    fi

    SEARCH_TEXT="$1"

    # 設定顏色代碼
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[1;33m'
    BLUE='\033[0;34m'
    CYAN='\033[0;36m'
    BOLD='\033[1m'
    NC='\033[0m'

    # 處理 macOS 的字元編碼
    export LC_ALL=C
    export LANG=C

    # 分隔線函數
    print_separator() {
    echo -e "${CYAN}----------------------------------------${NC}"
    }

    print_file_separator() {
    echo -e "\n${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    }

    print_separator_space() {
    echo -e ""
    }

    # 建構排除目錄的 find 參數
    EXCLUDE_PATTERN=""

    # 處理預設排除目錄
    if [ "$USE_DEFAULT_EXCLUDES" = true ]; then
    for dir in "${DEFAULT_EXCLUDES[@]}"; do
    EXCLUDE_PATTERN="$EXCLUDE_PATTERN -not -path '*/$dir/*'"
    done
    fi

    # 處理額外的排除目錄
    if [ ! -z "$EXCLUDE_DIRS" ]; then
    IFS=',' read -ra EXTRA_EXCLUDES <<< "$EXCLUDE_DIRS"
    for dir in "${EXTRA_EXCLUDES[@]}"; do
    EXCLUDE_PATTERN="$EXCLUDE_PATTERN -not -path '*/$dir/*'"
    done
    fi

    # 顯示搜尋資訊
    echo -e "${GREEN}開始在 ${BLUE}$SEARCH_DIR${GREEN} 目錄下搜尋 '${YELLOW}$SEARCH_TEXT${GREEN}'${NC}"
    if [ "$USE_DEFAULT_EXCLUDES" = true ]; then
    echo -e "${GREEN}使用預設排除目錄${NC}"
    fi
    if [ ! -z "$EXCLUDE_DIRS" ]; then
    echo -e "${GREEN}額外排除的目錄: ${YELLOW}$EXCLUDE_DIRS${NC}"
    fi
    # echo ""

    # 創建臨時檔案來儲存結果
    TEMP_FILE=$(mktemp)
    MATCHES_FILE=$(mktemp)

    # 執行搜尋並儲存結果
    eval "find '$SEARCH_DIR' -type f $EXCLUDE_PATTERN -print0" | \
    while IFS= read -r -d $'\0' file; do
    if grep -l $IGNORE_CASE "$SEARCH_TEXT" "$file" > /dev/null 2>&1; then
    echo "$file" >> "$TEMP_FILE"

    # 打印檔案標題
    # print_file_separator
    print_separator
    echo -e "${GREEN}${NC} ${CYAN}${BOLD} $file${NC}"
    # print_file_separator

    grep -n $IGNORE_CASE "$SEARCH_TEXT" "$file" 2>/dev/null | \
    while IFS=: read -r line content; do
    echo "1" >> "$MATCHES_FILE"
    echo -e "${GREEN}${NC} ${YELLOW} $line${NC} ${content}"
    # echo -e "${GREEN}│${NC} ${content}"
    # print_separator
    done
    fi
    done

    # 計算統計資訊
    FOUND_FILES=$(wc -l < "$TEMP_FILE")
    FOUND_MATCHES=$(wc -l < "$MATCHES_FILE")

    # 清理臨時檔案
    rm "$TEMP_FILE"
    rm "$MATCHES_FILE"

    # 顯示搜尋結果統計
    echo -e "\n${BOLD}${GREEN}搜尋完成${NC}"
    echo -e "${BLUE}┌─────────────────────────────────────┐${NC}"
    echo -e "${BLUE}${NC} 找到 ${YELLOW}$FOUND_FILES${NC} 個檔案"
    echo -e "${BLUE}${NC}${YELLOW}$FOUND_MATCHES${NC} 處匹配"
    echo -e "${BLUE}└─────────────────────────────────────┘${NC}"