在练习bash时,我尝试编写一个脚本,在主目录中搜索主目录中的重复文件并删除它们。这是我的脚本现在的样子。
#!/bin/bash
# create-list: create a list of regular files in a directory
declare -A arr1 sumray origray
if [[ -d "$HOME/$1" && -n "$1" ]]; then
echo "$1 is a directory"
else
echo "Usage: create-list Directory | options" >&2
exit 1
fi
for i in $HOME/$1/*; do
[[ -f $i ]] || continue
arr1[$i]="$i"
done
for i in "${arr1[@]}"; do
Name=$(sed 's/[][?*]/\\&/g' <<< "$i")
dupe=$(find ~ -name "${Name##*/}" ! -wholename "$Name")
if [[ $(find ~ -name "${Name##*/}" ! -wholename "$Name") ]]; then
mapfile -t sumray["$i"] < <(find ~ -name "${Name##*/}" ! -wholename "$Name")
origray[$i]=$(md5sum "$i" | cut -c 1-32)
fi
done
for i in "${!sumray[@]}"; do
poten=$(md5sum "$i" | cut -c 1-32)
for i in "${!origray[@]}"; do
if [[ "$poten" = "${origray[$i]}" ]]; then
echo "${sumray[$i]} is a duplicate of $i"
fi
done
done
最初,mapfile -t sumray["$i"] < <(find ~ -name "${Name##*/}" ! -wholename "$Name")
现在在哪里,我的行如下:
sumray["$i"]=$(find ~ -name "${Name##*/}" ! -wholename "$Name")
这将find的输出保存到数组中。但我有一个问题。如果单个文件有多个重复项,则find找到的所有位置都将保存为单个值。我想我可以使用mapfile命令来解决这个问题,但现在它根本没有保存到我的数组中。这是否与我使用关联数组的事实有关?或者我在其他地方搞砸了?
答案 0 :(得分:1)
我不确定我是否可以回答我自己的问题,但我认为我应该发布解决问题的方法。
事实证明,mapfile命令根本不适用于关联数组。所以我的修复是将find
的输出保存到文本文件,然后将该信息存储在索引数组中。我测试了几次,但我似乎还没有遇到任何错误。
这是我完成的剧本。
#!/bin/bash
# create-list: create a list of regular files in a directory
declare -A arr1 origray
declare indexray
#Verify that Parameter is a directory.
if [[ -d "$HOME/$1/" && -n "$1" ]]; then
echo "Searching for duplicates of files in $1"
else
echo "Usage: create-list Directory | options" >&2
exit 1
fi
#create list of files in specified directory
for i in $HOME/${1%/}/*; do
[[ -f $i ]] || continue
arr1[$i]="$i"
done
#search for all duplicate files in the home directory
#by name
#find checksum of files in specified directory
for i in "${arr1[@]}"; do
Name=$(sed 's/[][?*]/\\&/g' <<< "$i")
if [[ $(find ~ -name "${Name##*/}" ! -wholename "$Name") ]]; then
find ~ -name "${Name##*/}" ! -wholename "$Name" >> temp.txt
origray[$i]=$(md5sum "$i" | cut -c 1-32)
fi
done
#create list of duplicate file locations.
if [[ -f temp.txt ]]; then
mapfile -t indexray < temp.txt
else
echo "No duplicates were found."
exit 0
fi
#compare similarly named files by checksum and delete duplicates
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 $1."
fi
done
count=$((count+1))
done
rm temp.txt
这有点草率,但它做了它应该做的事情。 md5sum可能不是检查文件重复的最佳方法,但它可以工作。我所要做的就是将echo "${indexray[$count]} is a duplicate of a file in $1."
替换为rm -i ${indexray[$count]}
,这样做很不错。
所以我的下一个问题必须是......为什么mapfile不能与关联数组一起工作?