使用 mapfile 将输出保存到关联数组

Using mapfile to save output to associative arrays

在实践中bash,我尝试编写一个脚本,在主目录中搜索主目录中的重复文件并将其删除。这是我的脚本现在的样子。

#!/bin/bash

# create-list: create a list of regular files in a directory

declare -A arr1 sumray origray

if [[ -d "$HOME/" && -n "" ]]; then
    echo " is a directory"
else
    echo "Usage: create-list Directory | options" >&2
    exit 1
fi

for i in $HOME//*; 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 找到的所有位置都将保存为一个值。我想我可以使用 mapfile 命令来解决这个问题,但现在它根本没有将任何内容保存到我的数组中。它与我使用关联数组的事实有关吗?还是我只是在其他地方搞砸了?

我不确定我是否可以回答我自己的问题,但我想我应该 post 我是如何解决我的问题的。

事实证明,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//" && -n "" ]]; then
    echo "Searching for duplicates of files in "
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 ."
        fi
    done
    count=$((count+1))
done

rm temp.txt

这有点草率,但它做了它应该做的事情。 md5sum 可能不是检查文件重复项的最佳方法,但它确实有效。我所要做的就是用 rm -i ${indexray[$count]} 替换 echo "${indexray[$count]} is a duplicate of a file in ." 就可以了。

所以我的下一个问题是...为什么 mapfile 不能与关联数组一起使用?