文件查找脚本#
脚本说明#
文件查找脚本用于根据多种条件查找文件,包括文件名、大小、修改时间、文件类型等,并支持多种输出格式。
脚本代码#
#!/bin/bash
# 文件查找脚本
# 功能:根据多种条件查找文件
# 作者:System Admin
# 日期:2026-01-01
set -euo pipefail
# 配置变量
SEARCH_PATH="."
OUTPUT_FORMAT="list"
MAX_RESULTS=0
CASE_SENSITIVE=false
VERBOSE=false
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 日志函数
log() {
local level=$1
shift
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] [$level] $@"
}
log_info() {
log "INFO" "$@"
}
log_error() {
log "ERROR" "$@"
}
# 按文件名查找
find_by_name() {
local name_pattern=$1
local path=${2:-.}
log_info "按文件名查找: $name_pattern"
if [ "$CASE_SENSITIVE" = true ]; then
find "$path" -name "$name_pattern"
else
find "$path" -iname "$name_pattern"
fi
}
# 按文件类型查找
find_by_type() {
local file_type=$1
local path=${2:-.}
log_info "按文件类型查找: $file_type"
case $file_type in
file)
find "$path" -type f
;;
dir)
find "$path" -type d
;;
link)
find "$path" -type l
;;
*)
log_error "无效的文件类型: $file_type"
return 1
;;
esac
}
# 按文件大小查找
find_by_size() {
local size_condition=$1
local path=${2:-.}
log_info "按文件大小查找: $size_condition"
find "$path" -type f -size "$size_condition"
}
# 按修改时间查找
find_by_mtime() {
local time_condition=$1
local path=${2:-.}
log_info "按修改时间查找: $time_condition"
find "$path" -type f -mtime "$time_condition"
}
# 按文件内容查找
find_by_content() {
local content_pattern=$1
local path=${2:-.}
log_info "按文件内容查找: $content_pattern"
if [ "$CASE_SENSITIVE" = true ]; then
grep -r "$content_pattern" "$path" --include="*" -l
else
grep -ri "$content_pattern" "$path" --include="*" -l
fi
}
# 按权限查找
find_by_permission() {
local permission=$1
local path=${2:-.}
log_info "按权限查找: $permission"
find "$path" -perm "$permission"
}
# 按所有者查找
find_by_owner() {
local owner=$1
local path=${2:-.}
log_info "按所有者查找: $owner"
find "$path" -user "$owner"
}
# 按组查找
find_by_group() {
local group=$1
local path=${2:-.}
log_info "按组查找: $group"
find "$path" -group "$group"
}
# 查找空文件
find_empty() {
local path=${1:-.}
log_info "查找空文件"
find "$path" -type f -empty
}
# 查找大文件
find_large_files() {
local size_threshold=${1:-100M}
local path=${2:-.}
log_info "查找大文件 (> $size_threshold)"
find "$path" -type f -size "+$size_threshold" -exec ls -lh {} \;
}
# 查找重复文件
find_duplicates() {
local path=${1:-.}
log_info "查找重复文件"
find "$path" -type f -exec md5sum {} \; | \
sort | uniq -d -w 32 | \
cut -d' ' -f3-
}
# 格式化输出
format_output() {
local format=$1
local files=($2)
case $format in
list)
for file in "${files[@]}"; do
echo "$file"
done
;;
detailed)
for file in "${files[@]}"; do
ls -lh "$file"
done
;;
table)
printf "%-50s %-10s %-10s %-20s\n" "文件名" "大小" "权限" "修改时间"
printf "%-50s %-10s %-10s %-20s\n" "$(printf '%.50s' "$(echo "----------" | tr '-' ' '))" "----------" "----------" "--------------------"
for file in "${files[@]}"; do
local size=$(ls -lh "$file" | awk '{print $5}')
local perms=$(ls -ld "$file" | awk '{print $1}')
local mtime=$(ls -ld "$file" | awk '{print $6, $7, $8}')
printf "%-50s %-10s %-10s %-20s\n" "$file" "$size" "$perms" "$mtime"
done
;;
json)
echo "["
local first=true
for file in "${files[@]}"; do
if [ "$first" = false ]; then
echo ","
fi
first=false
local size=$(stat -c %s "$file")
local perms=$(stat -c %a "$file")
local mtime=$(stat -c %Y "$file")
printf " {"
printf "\"name\": \"%s\", " "$file"
printf "\"size\": %d, " "$size"
printf "\"permissions\": \"%s\", " "$perms"
printf "\"mtime\": %d" "$mtime"
printf "}"
done
echo ""
echo "]"
;;
*)
log_error "无效的输出格式: $format"
return 1
;;
esac
}
# 复合查找
complex_find() {
local path=$1
shift
log_info "执行复合查找"
local find_cmd="find \"$path\""
while [ $# -gt 0 ]; do
case $1 in
-name)
find_cmd="$find_cmd -name \"$2\""
shift 2
;;
-type)
find_cmd="$find_cmd -type \"$2\""
shift 2
;;
-size)
find_cmd="$find_cmd -size \"$2\""
shift 2
;;
-mtime)
find_cmd="$find_cmd -mtime \"$2\""
shift 2
;;
-perm)
find_cmd="$find_cmd -perm \"$2\""
shift 2
;;
-user)
find_cmd="$find_cmd -user \"$2\""
shift 2
;;
-group)
find_cmd="$find_cmd -group \"$2\""
shift 2
;;
*)
log_error "无效的选项: $1"
return 1
;;
esac
done
eval "$find_cmd"
}
# 显示帮助
show_help() {
echo "用法: $0 [选项] <查找模式> [参数]"
echo ""
echo "选项:"
echo " -p <路径> 搜索路径(默认: .)"
echo " -f <格式> 输出格式(list/detailed/table/json)"
echo " -m <数量> 最大结果数量(0=无限制)"
echo " -c 区分大小写"
echo " -v 详细输出"
echo " -h 显示帮助信息"
echo ""
echo "查找模式:"
echo " name <模式> 按文件名查找"
echo " type <类型> 按文件类型查找(file/dir/link)"
echo " size <条件> 按文件大小查找(如: +100M, -1K)"
echo " mtime <条件> 按修改时间查找(如: -7, +30)"
echo " content <模式> 按文件内容查找"
echo " perm <权限> 按权限查找(如: 755)"
echo " owner <用户> 按所有者查找"
echo " group <组> 按组查找"
echo " empty 查找空文件"
echo " large [大小] 查找大文件(默认: 100M)"
echo " duplicates 查找重复文件"
echo " complex <选项>... 复合查找"
echo ""
echo "示例:"
echo " $0 name \"*.txt\""
echo " $0 type file"
echo " $0 size \"+100M\""
echo " $0 mtime \"-7\""
echo " $0 content \"error\""
echo " $0 perm 755"
echo " $0 large"
echo " $0 duplicates"
echo " $0 complex -name \"*.log\" -mtime -7 -size +1M"
}
# 主函数
main() {
# 解析选项
while getopts "p:f:m:cvh" opt; do
case $opt in
p)
SEARCH_PATH="$OPTARG"
log_info "搜索路径: $SEARCH_PATH"
;;
f)
OUTPUT_FORMAT="$OPTARG"
log_info "输出格式: $OUTPUT_FORMAT"
;;
m)
MAX_RESULTS="$OPTARG"
log_info "最大结果: $MAX_RESULTS"
;;
c)
CASE_SENSITIVE=true
log_info "区分大小写"
;;
v)
VERBOSE=true
log_info "详细输出"
;;
h)
show_help
exit 0
;;
*)
log_error "无效选项: $opt"
show_help
exit 1
;;
esac
done
shift $((OPTIND - 1))
# 检查参数
if [ $# -eq 0 ]; then
log_error "缺少查找模式"
show_help
exit 1
fi
# 检查搜索路径
if [ ! -d "$SEARCH_PATH" ]; then
log_error "搜索路径不存在: $SEARCH_PATH"
exit 1
fi
MODE=$1
shift
# 执行查找
local results=()
case $MODE in
name)
if [ $# -eq 0 ]; then
log_error "缺少文件名模式"
exit 1
fi
mapfile -t results < <(find_by_name "$1" "$SEARCH_PATH")
;;
type)
if [ $# -eq 0 ]; then
log_error "缺少文件类型"
exit 1
fi
mapfile -t results < <(find_by_type "$1" "$SEARCH_PATH")
;;
size)
if [ $# -eq 0 ]; then
log_error "缺少大小条件"
exit 1
fi
mapfile -t results < <(find_by_size "$1" "$SEARCH_PATH")
;;
mtime)
if [ $# -eq 0 ]; then
log_error "缺少时间条件"
exit 1
fi
mapfile -t results < <(find_by_mtime "$1" "$SEARCH_PATH")
;;
content)
if [ $# -eq 0 ]; then
log_error "缺少内容模式"
exit 1
fi
mapfile -t results < <(find_by_content "$1" "$SEARCH_PATH")
;;
perm)
if [ $# -eq 0 ]; then
log_error "缺少权限"
exit 1
fi
mapfile -t results < <(find_by_permission "$1" "$SEARCH_PATH")
;;
owner)
if [ $# -eq 0 ]; then
log_error "缺少用户名"
exit 1
fi
mapfile -t results < <(find_by_owner "$1" "$SEARCH_PATH")
;;
group)
if [ $# -eq 0 ]; then
log_error "缺少组名"
exit 1
fi
mapfile -t results < <(find_by_group "$1" "$SEARCH_PATH")
;;
empty)
mapfile -t results < <(find_empty "$SEARCH_PATH")
;;
large)
local size=${1:-100M}
mapfile -t results < <(find_large_files "$size" "$SEARCH_PATH")
;;
duplicates)
mapfile -t results < <(find_duplicates "$SEARCH_PATH")
;;
complex)
mapfile -t results < <(complex_find "$SEARCH_PATH" "$@")
;;
*)
log_error "无效的查找模式: $MODE"
show_help
exit 1
;;
esac
# 限制结果数量
if [ $MAX_RESULTS -gt 0 ] && [ ${#results[@]} -gt $MAX_RESULTS ]; then
log_info "限制结果数量: ${MAX_RESULTS}"
results=("${results[@]:0:$MAX_RESULTS}")
fi
# 输出结果
log_info "找到 ${#results[@]} 个结果"
format_output "$OUTPUT_FORMAT" "${results[@]}"
}
# 执行主函数
main "$@"使用说明#
添加执行权限:
chmod +x file_finder.sh基本用法:
# 按文件名查找 ./file_finder.sh name "*.txt" # 按文件类型查找 ./file_finder.sh type file # 按文件大小查找 ./file_finder.sh size "+100M" # 按修改时间查找 ./file_finder.sh mtime "-7" # 按文件内容查找 ./file_finder.sh content "error" # 查找大文件 ./file_finder.sh large高级选项:
# 指定搜索路径 ./file_finder.sh -p /var/log name "*.log" # 使用详细输出格式 ./file_finder.sh -f detailed name "*.txt" # 限制结果数量 ./file_finder.sh -m 10 type file # 区分大小写 ./file_finder.sh -c name "File.txt" # 复合查找 ./file_finder.sh complex -name "*.log" -mtime -7 -size +1M
功能特点#
- 支持多种查找条件
- 文件名、类型、大小、时间等
- 文件内容搜索
- 权限和所有者查找
- 复合条件查找
- 多种输出格式
- 结果数量限制
- 大小写敏感选项
依赖项#
- find: 用于文件查找
- grep: 用于内容搜索
- md5sum: 用于查找重复文件
注意事项#
- 文件内容搜索可能较慢
- 查找大目录时注意性能
- JSON格式输出需要正确处理
- 复合查找时注意条件顺序
- 权限查找需要相应权限