2016-11-29 57 views
-1

最終,我想擺脫重複條目顯示我的數組的可能性。我這樣做的原因是因爲我正在研究比較兩個目錄,搜索和刪除重複文件的腳本。潛在的重複文件存儲在一個數組中,並且只有與原始文件具有相同的名稱和校驗和才能刪除這些文件。所以如果有重複的條目,我會遇到一些小錯誤,其中md5試圖找到不存在的文件的校驗和(因爲它已經被刪除),或者rm試圖刪除已經被刪除的文件。如何對數組的內容進行排序?

這是腳本的一部分。

compare() 
{ 

read -p "Please enter two directories: " dir1 dir2 

if [[ -d "$dir1" && -d "$dir2" ]]; then 
    echo "Searching through $dir2 for duplicates of files in $dir1..." 
else 
    echo "Invalid entry. Please enter valid directories." >&2 
    exit 1 
fi 

#create list of files in specified directory 
while read -d $'\0' file; do 
    test_arr+=("$file") 
done < <(find $dir1 -print0) 

#search for all duplicate files in the home directory 
#by name 
#find checksum of files in specified directory 
tmpfile=$(mktemp -p $dir1 del_logXXXXX.txt) 


for i in "${test_arr[@]}"; do 
    Name=$(sed 's/[][?*]/\\&/g' <<< "$i") 

    if [[ $(find $dir2 -name "${Name##*/}" ! -wholename "$Name") ]]; then 
     [[ -f $i ]] || continue 
     find $dir2 -name "${Name##*/}" ! -wholename "$Name" >> $tmpfile 
     origray[$i]=$(md5sum "$i" | cut -c 1-32) 
    fi 
done 

#create list of duplicate file locations. 
dupe_loc 

#compare similarly named files by checksum and delete duplicates 
local count=0 
for i in "${!indexray[@]}"; do 
    poten=$(md5sum "${indexray[$i]}" | cut -c 1-32) 
    for i in "${!origray[@]}"; do 
     if [[ "$poten" = "${origray[$i]}" ]]; then 
      echo "${indexray[$count]} is a duplicate of a file in $dir1." 
      rm -v "${indexray[$count]}" 
      break 
     fi 
    done 
    count=$((count+1)) 
done 
exit 0 
} 

dupe_loc是以下功能。

dupe_loc() 
{ 
if [[ -s $tmpfile ]]; then 
    mapfile -t indexray < $tmpfile 
else 
    echo "No duplicates were found." 
    exit 0 
fi 
} 

我想解決這個問題是使用的sortuniq命令處置陣列中的重複條目的最佳方式。但即使有流程替代,我在嘗試這樣做時也會遇到錯誤。

+1

你能進一步簡化問題嗎?假設你有兩個帶有文件的目錄,並且你想要一個只有來自兩個目錄的唯一內容的第三個目錄? – NinjaGaiden

+1

'sort -u -kN,M'應該足夠了。對於這個問題,請閱讀http://stackoverflow.com/help/mcve,然後再發布更多Q​​.祝你好運。 – shellter

+0

一個更簡單的方法是用文件名(無路徑)填充'test_arr',一旦你填充了'test_arr',只需循環名稱和'test',如果dir2中有一個文件名爲。 'test_arr + =(「$ {file ## * /}」)',然後'declare -a dups;因爲我在「$ {test_arr [@]}」;做[-f「$ dir2/$ i」] && dups + =(「$ i」); done'你現在有'dups'中的重複列表。 –

回答

0

第一件事是第一件事。 Bash數組排序已經在這裏回答:How to sort an array in BASH

這就是說,我不知道對數組進行排序會有很大的幫助。看起來更簡單的解決方案就是將你的md5檢查和rm語句包裝在if語句中:

if [ -f origarr[$i]} ]; do #True if file exists and is a regular file. 
    #file exists 
    ... 
    rm ${origarr[$i]} 
fi