Linux文件夾對比并提取的差分文件技巧-rsync的妙用
需求
最近團隊正在開發一個版本對比工具,要求是把A1文件夾與A2對比,將A2中的增量部分,輸出到update文件夾中,生成增量升級包/差分包。
方案研究
實現該功能的第一反應是,分別遍歷2個文件夾,進行單個文件對比是否存在于MD5比對,并輸出結果,但是這個絕對是最低級做法,并且時間復雜度為O(n2),基本上就是直接否定。
后來深入研究了內核補丁常用的diff + patch方案,即
diff -urNa dir1 dir2
生成了差異文件后,用patch命令進行文件的復制或者文件內容修改。這個很明顯如果要實現需求還是要去人工代碼解析diff的結果才行。也是復雜了。
突然。。或者是說類似動畫片里面柯南那句masaka 搭配場景閃現的效果出現了...
能分析出文件夾差異,還能支持多種對比模式checksum、mod-time、size的,還能過濾掉svn不需要提交的二進制文件、中間文件,經常用于服務器端增量同步的,不就是rsync么。。。(該處rsync應該字號放大十倍,但是markdown改不了)
現在唯一要解決的問題是,rsync是從A文件夾同步到B文件夾,是否可以重定向這個同步的文件到C文件夾而不改變B文件夾內容呢?
翻看了rsync man之后oh ~ 這個--dry-run參數是演示trial的意思。。也就是說使用了dry-run就只能看,不會變了。。。
馬上開始coding。。。
STEP1
A1.1是新文件夾,A1.0是舊文件夾,out是放置 A1.0到A1.1的保持目錄結構的增量文件。
rsync --dry-run -rcnC --out-format="%n" A1.1/ A1.0/
注意該處的-C參數是按照cvs的ignore規則來過濾不需要同步的文件,在CVS中,默認是不會提交二進制文件的,所以如果需要進行二進制文件提取,那就不要加C.
執行了該命令后,得到了一個A1目錄的文件列表:
A1.1/system/app/
A1.1/system/app/A.apk
A1.1/system/app/B.apk
A1.1/system/app/C.apk
也就是差異文件,由于這里默認會顯示出文件夾,所以要過濾掉以『/』結尾的文件夾的顯示
rsync --dry-run -rcnC --out-format="%n" A1.1/ A1.0/ |grep -v "/$"
這樣就得到了一個純增量文件的列表
STEP2
有了文件列表,復制的操作方法就很多了。可以繼續使用rsync同步到新的out目錄,以防止多次執行后錯誤文件修復問題
完整代碼
rsync --dry-run -rcnC --out-format="%n" A1.1/ A1.0/ |grep -v "/$"|xargs -I{} rsync -R A1/./{} out/
搞定!
總結
其實我們身邊有很多常用的工具,具備強大的功能。其實作為程序猿這個群體,『浮躁』是一個界限將高手與菜鳥分開。其實高手并不是掌握了多少語言,懂了多少模式、收藏了多少的開源代碼工具...
而是需要踏踏實實走好每一步。