我試圖寫一個bash腳本,可以只通過2個或多個目錄位置如何通過名稱和在2個或多個目錄
diff -srq Ear2.ear/ Ear1.ear/ | grep identical
之間的名字給的相同文件的列表相同位置找到相同的文件
,但似乎這是比較內容。
我已經有一個文件,其中包含我需要比較的所有目標目錄的列表。但是,我需要在比較時排除某些子直接存儲。
我試圖寫一個bash腳本,可以只通過2個或多個目錄位置如何通過名稱和在2個或多個目錄
diff -srq Ear2.ear/ Ear1.ear/ | grep identical
之間的名字給的相同文件的列表相同位置找到相同的文件
,但似乎這是比較內容。
我已經有一個文件,其中包含我需要比較的所有目標目錄的列表。但是,我需要在比較時排除某些子直接存儲。
這充分利用了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)
cd
所以,我們不包括在find
輸出父目錄。find
以打印除給定子文件夾之外的所有文件。sort
,這樣我們就可以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
放在最後,以防你稍後改變它。
陣列橫截面是解決這個問題的有趣方法。
$ 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
可能有用http://superuser.com/questions/228763/how-to-diff-file-names-in-two-directories - 不寫入中間文件? – whrrgarbl
,我在上面挑選。我不知道如何排除某些子目錄 – Vik
要澄清,上述命令的問題是您不知道如何排除某些子目錄?或者你也希望它只比較文件名而不是內容? – whrrgarbl