以前在Windows上一直使用TotalCmd,它的比较功能非常棒。不论是目录还是文件,只要按下F10,就能够比较,还能够同步,非常方便。切换到Mac也有好几年了,一直没有找到完全匹配上的替代品。现在用的是ForkLift,常用功能还可以,但是比较功能差距很大。目前正在想办法自己写一些脚本增强一下功能。
目前实现了一个脚本,通过ForkLift
调用,可以满足基本的比较功能:
- 使用
file
判断文件类型,对文本类型调用FileMerge
进行源码比较; - 如果不是,则只用
cmp
功能比较内容是否相等; - 后期考虑增加对目录类型的支持,引入目录比较工具。
1. 代码
1#!/bin/bash
2# error "Message"
3function error() {
4 osascript <<EOT
5 tell app "System Events"
6 display dialog "$1" buttons {"OK"} default button 1 with icon caution with title "$(basename $0)"
7 return -- Suppress result
8 end tell
9EOT
10}
11
12src=$1
13dst=$2
14
15if [ "$src" = "" -o "$dst" = "" ]; then
16 error "Please choose two files to compare..."
17 exit 1
18fi
19
20# 获取文件类型
21fi1=`file -I -b $src`
22fi2=`file -I -b $dst`
23
24# 只有在全是文本类型的时候使用FileMerge进行比较
25if [[ "$fi1" =~ ^text/.* && "$fi2" =~ ^text/.* ]]; then
26 /Applications/Xcode.app/Contents/Applications/FileMerge.app/Contents/MacOS/FileMerge -left $1 -right $2 >/dev/null 2>&1 &
27else
28 # 否则,使用cmp比较,直接显示结果
29 cmp -s "$1" "$2"
30 if [ $? -eq 0 ]; then
31 error "Same. Files: \n ${src##*/} \n ${dst##*/}"
32 else
33 error "Not same. Files: \n ${src##*/} \n ${dst##*/}"
34 fi
35fi
2. 用到的工具
2.1 file
file
命令可以用来获取文件的类型。例如:
1> file -I Application.java
2Application.java: text/x-c; charset=us-ascii
3
4> file -I soapui-settings.xml
5soapui-settings.xml: text/xml; charset=us-ascii
6
7> file -I *.jpg
8mmexport1576413628825.jpg: image/jpeg; charset=binary
9
10> file -I *.mkv
11[终结者:黑暗命运].Terminator.Dark.Fate.2019.BluRay.720p.x264.AC3-CMCT.mkv: video/x-matroska; charset=binary
file
命令通过多种分析来最终确定一个文件的类型(包括:filesystem tests
, magic tests
, language tests
),具体的可以看帮助。
常用的几个参数介绍一下:
-I, --mime
打印文件的mime
类型编码。也就是打印诸如:text/plain; charset=us-ascii
这种格式信息而不是ASCII text
。这种返回的类型比较规范,例如上面代码中就是通过判断返回值是否以text
开头来判断是否是一个文本文件。-b, --brief
精简模式。不再输出结果中打印文件名。方便代码中处理。
2.2 cmp
cmp
命令是一个命令行比较工具,可以按字节比较两个文件是否相同。用到的参数介绍:
-s, --silent
静默比较方式,命令不输出任何内容。需要判断命令的返回值是否为0判断两个文件是否相等。
2.3 FileMerge
FileMerge
是XCode
中自带的一个文件比较工具,可以用来比较源码,它支持命令行调用(通过-left
, -right
指定文件),而且比较功能也不错。当然,也可以替换成其他的商业软件以获得更强的比较功能。