实现支持含空格路径的自定义diff目录对比Bash脚本
解决Bash脚本
dirt中含空格路径的diff输出解析与完整实现 核心问题:含空格路径的正确提取
用awk按空格分割diff -qs的输出会直接失效——比如遇到Files dir1/My Documents/file.txt and dir2/My Documents/file.txt are identical这类行,awk会把My当成独立字段,完全拆错路径。
改用Bash参数扩展${line%:*}就能精准提取路径:它会从行尾往前匹配第一个:并截去后续内容,不管路径里有多少空格,都能完整拿到包含路径的前缀部分,再进一步拆分左右路径即可。
完整dirt脚本实现
#!/bin/bash # 检查参数合法性 if [ $# -ne 2 ]; then echo "用法: $0 <目录1> <目录2>" exit 1 fi DIR1="$1" DIR2="$2" # 处理diff输出的各类场景 diff -qr "$DIR1" "$DIR2" | while IFS= read -r line; do case "$line" in # 内容相同的文件 "Files"*"are identical") path_part="${line% are identical}" left_path="${path_part#Files }" left_path="${left_path% and *}" right_path="${path_part#* and }" printf "%-40s [IDENTICAL] %s\n" "$left_path" "$right_path" ;; # 内容不同的文件 "Files"*"differ") path_part="${line% differ}" left_path="${path_part#Files }" left_path="${left_path% and *}" right_path="${path_part#* and }" printf "%-40s [DIFFERENT] %s\n" "$left_path" "$right_path" ;; # 仅单侧存在的文件/目录 "Only in"*":") dir_part="${line#Only in }" dir_part="${dir_part%:*}" file="${line#*: }" full_path="$dir_part/$file" if [[ "$full_path" == "$DIR1"* ]]; then printf "%-40s [MISSING] \n" "$full_path" else printf " [MISSING] %s\n" "$full_path" fi ;; esac done # 补充处理公共子目录 comm -12 <(find "$DIR1" -type d | sort) <(find "$DIR2" -type d | sort) | while IFS= read -r dir; do [[ "$dir" == "$DIR1" || "$dir" == "$DIR2" ]] && continue rel_dir="${dir#$DIR1/}" printf "%-40s [DIRECTORY] %s/%s\n" "$dir" "$DIR2" "$rel_dir" done
脚本功能说明
- 仅左侧存在的资源:左栏显示完整路径,右栏标记
[MISSING] - 仅右侧存在的资源:右栏显示完整路径,左栏标记
[MISSING] - 内容一致的文件:左右栏均显示路径,中间标记
[IDENTICAL] - 内容差异的文件:左右栏均显示路径,中间标记
[DIFFERENT] - 公共子目录:左右栏均显示路径,中间标记
[DIRECTORY](自动跳过根目录,仅展示子目录)
可调细节
输出列宽可修改printf中的%-40s参数,适配你的终端宽度;若不需要相对路径展示公共子目录,直接输出$dir即可。
内容的提问来源于stack exchange,提问作者SystemTheory
相关产品推荐
相关产品推荐

