dm-design/cmd.sh

204 lines
6.4 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# (v9) 支持新格式:名称 # 说明 # 命令
interactive_mode() {
local command_file="${1:-/Users/linbin/SynologyDrive/附件/590/cmd/my_commands}"
local initial_query="${2:-}"
# 使用临时文件来避免复杂的引号转义问题
local preview_script="/tmp/preview_$$"
cat > "$preview_script" << 'EOF'
#!/bin/bash
command_file="$1"
line_content="$2"
# trim空格
name_part=$(echo "$line_content" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
# 从原文件中获取完整的行
full_line=$(grep -v "^#" "$command_file" | awk -F'#' -v name="$name_part" '{
first_field = $1
gsub(/^[[:space:]]+|[[:space:]]+$/, "", first_field)
if (first_field == name) print $0
}' | head -1)
if [ -n "$full_line" ]; then
# 提取三部分:名称、说明、命令
name=$(echo "$full_line" | awk -F'#' '{print $1}' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
desc=$(echo "$full_line" | awk -F'#' '{print $2}' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
command_part=$(echo "$full_line" | awk -F'#' '{print $3}' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
# 预览窗口的显示逻辑
echo "--- 名称 ---"
echo "$name"
echo ""
echo "--- 说明 ---"
echo "$desc"
echo ""
echo "--- 命令 ---"
if [ -f "$command_part" ]; then
echo "$command_part"
echo ""
echo "--- 文件内容 ---"
cat "$command_part" 2>/dev/null || echo "无法读取文件内容"
else
echo "$command_part"
fi
else
echo "未找到对应的命令"
fi
EOF
chmod +x "$preview_script"
# --- 模糊搜索 ---
local selected_line
selected_line=$(grep -v "^#" "$command_file" |
# 使用#作为分隔符让fzf只搜索第一部分名称
awk -F'#' '{print $1}' |
sed 's/^[[:space:]]*//;s/[[:space:]]*$//' |
fzf --height=40% --tac \
--query="$initial_query" \
--header "↑↓ 选择, Enter 执行, Esc 退出 (或 cmd <快捷词> 直接调用)" \
--preview "$preview_script '$command_file' {}")
# 清理临时文件
rm -f "$preview_script"
# 如果用户选择了,获取名称部分
if [ -n "$selected_line" ]; then
selected_line=$(echo "$selected_line" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
fi
if [ -z "$selected_line" ]; then
echo "已取消。"
return 0
fi
# 从原文件中重新获取完整命令
local full_line
full_line=$(grep -v "^#" "$command_file" | awk -F'#' -v name="$selected_line" '{
first_field = $1
gsub(/^[[:space:]]+|[[:space:]]+$/, "", first_field)
if (first_field == name) print $0
}' | head -1)
# 提取三部分
local name_part desc_part command_to_run
name_part=$(echo "$full_line" | awk -F'#' '{print $1}' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
desc_part=$(echo "$full_line" | awk -F'#' '{print $2}' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
command_to_run=$(echo "$full_line" | awk -F'#' '{print $3}' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
echo "$name_part$desc_part"
# 执行逻辑 - 对sh文件使用source执行
if [ -f "$command_to_run" ]; then
if [[ "$command_to_run" == *.sh ]]; then
source "$command_to_run"
elif [ -x "$command_to_run" ]; then
"$command_to_run"
else
source "$command_to_run"
fi
else
eval "$command_to_run"
fi
}
cmd() {
local command_file="/Users/linbin/SynologyDrive/附件/590/cmd/my_commands"
# 检查命令文件是否存在
if [ ! -f "$command_file" ]; then
echo "命令文件 $command_file 不存在。"
return 1
fi
# --- 处理直接调用(支持模糊匹配)---
# 检查是否提供了参数 (如: cmd lsa)
if [ "$#" -gt 0 ]; then
# 将所有参数用空格连接起来构造精确匹配模式
local shortcut=""
for arg in "$@"; do
if [ -n "$shortcut" ]; then
shortcut="$shortcut $arg"
else
shortcut="$arg"
fi
done
# 统一使用模糊匹配逻辑处理所有输入
# 将所有参数用空格连接起来进行模糊匹配
local all_args=""
for arg in "$@"; do
if [ -n "$all_args" ]; then
all_args="$all_args $arg"
else
all_args="$arg"
fi
done
fuzzy_matches=$(grep -v "^#" "$command_file" | awk -v keywords="$all_args" -F'#' '
{
# 提取第一部分名称并trim空格
name_part = $1
gsub(/^[[:space:]]+|[[:space:]]+$/, "", name_part)
# 将关键字按空格分割并检查每个关键字是否都匹配
n = split(keywords, kw_array, " ")
match_all = 1
for (i = 1; i <= n; i++) {
# 检查关键字是否为空并且是否在name_part中存在
if (kw_array[i] != "" && index(name_part, kw_array[i]) == 0) {
match_all = 0
break
}
}
if (match_all == 1) print $0
}')
if [ -n "$fuzzy_matches" ]; then
# 统计匹配数量 - 只统计非空行
local match_count
match_count=$(echo "$fuzzy_matches" | grep -c '.')
if [ "$match_count" -eq 1 ]; then
# 只有一个模糊匹配,直接执行
local name_part desc_part command_to_run
name_part=$(echo "$fuzzy_matches" | awk -F'#' '{print $1}' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
desc_part=$(echo "$fuzzy_matches" | awk -F'#' '{print $2}' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
command_to_run=$(echo "$fuzzy_matches" | awk -F'#' '{print $3}' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
echo "$name_part$desc_part"
# 执行命令 - 对sh文件使用source执行
if [ -f "$command_to_run" ]; then
if [[ "$command_to_run" == *.sh ]]; then
source "$command_to_run"
elif [ -x "$command_to_run" ]; then
"$command_to_run"
else
source "$command_to_run"
fi
else
eval "$command_to_run"
fi
return 0
else
# 多个匹配,进入交互模式让用户选择
echo "找到 $match_count 个匹配项:"
echo "$fuzzy_matches" | awk -F'#' '{print $1}' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | nl -b a
echo ""
# 直接进入交互模式
interactive_mode "" "$all_args"
return 0
fi
else
echo "未找到匹配项,进入交互搜索模式..."
# 进入交互模式
interactive_mode "" "$all_args"
fi
# 如果没有提供参数,直接进入交互模式
else
interactive_mode
fi
}