如何用diff仅对比文件名而非文件内容并正确输出'differences!'
如何用diff仅对比文件名而非文件内容并正确输出'differences!'
你的问题出在命令的逻辑判断上——原来的command3把判断条件完全搞反了!
咱们先理清楚出错原因:当两个目录存在文件名差异时,diff会输出带<或>的行,接着grep '^[<>]'能匹配到内容,它的退出码是0,所以会触发&& echo "no difference";而当没有差异时,diff没有输出,grep找不到匹配内容,退出码是1,反而触发|| echo "differences!",完全和你预期的结果相反。
下面给你两种正确的写法,既能显示差异的文件名,又能准确输出判断结果:
方法一:清晰可靠的分步写法
这种写法会保存diff的结果和退出码,逻辑一目了然,还能处理错误情况:
DIR1="/media/x/8001G_GPTEXT4/Test1/E BOOKS" DIR2="/media/x/2000G_DOSNTFS/Test1/E BOOKS" # 执行diff对比文件名,保存输出结果和退出码 diff_result=$(diff <(find "$DIR1" -printf '%P\n' | sort) <(find "$DIR2" -printf '%P\n' | sort)) diff_exit_code=$? # 过滤并显示差异的文件名(< 代表仅在DIR1存在,> 代表仅在DIR2存在) echo "$diff_result" | grep '^[<>]' # 根据diff的退出码判断最终结果 if [ "$diff_exit_code" -eq 1 ]; then echo "differences!" elif [ "$diff_exit_code" -eq 0 ]; then echo "no difference" else echo "Error: 目录对比失败,请检查权限或路径是否正确!" fi
这里要记住diff的退出码规则:
- 0:两个目录的文件名完全一致
- 1:存在文件名差异
- 2:发生错误(比如目录不存在、权限不足)
方法二:更简洁的写法
如果不想保存结果,也可以用PIPESTATUS获取管道中第一个命令(也就是diff)的退出码:
DIR1="/media/x/8001G_GPTEXT4/Test1/E BOOKS" DIR2="/media/x/2000G_DOSNTFS/Test1/E BOOKS" # 先显示差异文件名 diff <(find "$DIR1" -printf '%P\n' | sort) <(find "$DIR2" -printf '%P\n' | sort) | grep '^[<>]' # 基于diff的退出码判断结果 if [ ${PIPESTATUS[0]} -eq 1 ]; then echo "differences!" else echo "no difference" fi
${PIPESTATUS[0]}会返回管道中第一个命令的退出状态,这样我们就跳过了grep的干扰,直接用diff的结果做判断。
备注:内容来源于stack exchange,提问作者joseph22
相关产品推荐
相关产品推荐

