2016-03-03 54 views
2

我試圖寫一個bash腳本,可以只通過2個或多個目錄位置如何通過名稱和在2個或多個目錄

diff -srq Ear2.ear/ Ear1.ear/ | grep identical 
之間的名字給的相同文件的列表相同位置找到相同的文件

,但似乎這是比較內容。

我已經有一個文件,其中包含我需要比較的所有目標目錄的列表。但是,我需要在比較時排除某些子直接存儲。

+0

可能有用http://superuser.com/questions/228763/how-to-diff-file-names-in-two-directories - 不寫入中間文件? – whrrgarbl

+0

,我在上面挑選。我不知道如何排除某些子目錄 – Vik

+0

要澄清,上述命令的問題是您不知道如何排除某些子目錄?或者你也希望它只比較文件名而不是內容? – whrrgarbl

回答

0

這充分利用了find實用的-prune選項排除目錄:

comm -1 -2 <(cd $1; find . -name "*" -path "./folder1" -prune -o -print | sort) <(cd $2; find . -name "*" -path "./folder1" -prune -o -print | sort) 
  1. cd所以,我們不包括在find輸出父目錄。
  2. 使用合適的參數運行find以打印除給定子文件夾之外的所有文件。
  3. 管道將進入sort,這樣我們就可以
  4. 通過進程替換使用comm實用程序只顯示線(即文件名)的共同點。

基本示例:

我的文件夾結構:

diffdir1/ 
    file1.txt 
    file2.txt 
    uniqueTo1.txt 
    folder1/ 
    file1.txt 
    folder2/ 
     file1.txt 
    folderUniqueTo1/ 
    file1.txt 

diffdir2/ 
    file1.txt 
    file2.txt 
    uniqueTo2.txt 
    folder1/ 
    file1.txt 
    folder2/ 
    file1.txt 

(內容做各種file1.txt S之間的不同,雖然我們在這裏不會檢查。)使用上面的腳本,我得到:

$ ./script.sh diffdir1 diffdir2 
. 
./file1.txt 
./file2.txt 

aka只有兩個文件與s阿姆名字。

作爲一個全面的檢查,如果我刪除命令的-path "./folder1" -prune -o -print一部分,這應該不再排除的東西folder1下:

$ ./script2.sh diffdir1 diffdir2 
. 
./file1.txt 
./file2.txt 
./folder1 
./folder1/file1.txt 

使用的目錄列表中選擇一個文件,這樣也只是一個問題修改find命令的不同參數。

實施例:排除多個子目錄

此命令將排除的文件夾./abc/xyz/obj64./abc/video,和./sim

comm -1 -2 <(cd $1; find . -name "*" \(-path "./abc/xyz/obj64" -o -path "./abc/video" -o -path "./sim" \) -prune -o -print | sort) <(cd $2; find . -name "*" \(-path "./abc/xyz/obj64" -o -path "./abc/video" -o -path "./sim" \) -prune -o -print | sort) 

注意的路徑列表必須放在括號\(\)的內部。 -o的意思是「或」,所以它現在檢查是否有任何路徑與修剪相匹配。

例如:僅包括匹配特定模式的

擴大關前面的例子中的文件,現在我們只返回文件匹配的模式。在這個例子中,我會搜索僅在.xml結尾的文件:

comm -1 -2 <(cd $1; find . \(-path "./abc/xyz/obj64" -o -path "./abc/video" -o -path "./sim" \) -prune -o -name "*.xml" -print | sort) <(cd $2; find . \(-path "./abc/xyz/obj64" -o -path "./abc/video" -o -path "./sim" \) -prune -o -name "*.xml" -print | sort) 

的此不同的是,-name論點後修剪搬到。如果您正在搜索所有文件("*"),這並沒有什麼區別,但是當您擁有一個模式時就很重要。所以最好把-name放在最後,以防你稍後改變它。

+0

應該是-path還是-not -path? – Vik

+0

它應該是'-path',帶有你想排除的路徑。我將添加我測試過的示例目錄結構和輸出。 – whrrgarbl

+0

和超過2個目錄? – SLePort

0

陣列橫截面是解決這個問題的有趣方法。

$ mkdir tmp1 tmp2 
$ touch tmp1/foo tmp1/bar tmp1/baz 
$ touch tmp2/foo tmp2/bar tmp2/slurm 
$ cd tmp1; a=(*); cd - 
$ cd tmp2; declare -A b; for f in *; do b[$f]=1; done; cd - 
$ for x in "${a[@]}"; do [[ "${b[$x]}" ]] && echo "$x"; done 
bar 
foo 

不過,你提到你「需要排除某些子directores而比較」,和你的diff包括-r,所以你看是選擇遞歸。

爲了達到這個目的,我建議使用bash的globstar,然後移除你不想要的部分。例如:

$ shopt -s globstar 
$ a=(**/*) 
$ for x in "${!a[@]}"; do [[ "${a[$x]}" = tmp3/* ]] && unset a[$x]; done 

注意globstar需要bash的版本4

相關問題