从文件夹中删除相同的文件

从文件夹中删除相同的文件

我正在使用 chroot 为我自己的操作系统构建软件包。我在存档文件中有 chroot,在构建过程开始时,它会下载两次并提取。我需要一个命令,从构建包的 chroot 文件夹中删除文件,这些文件与第二个 chroot 文件夹中的文件相同(例如通过其哈希值)。我尝试了 Unix StackExchange 中的几个命令,但没有一个起作用。

编辑:这必须是全自动的

答案1

fdupes

fdupes -drN dir1 dir2

这将删除两个目录中多次找到的所有内容。任何骗局的第一个发现的副本都会被保留。

有长选项:

fdupes --delete --recurse --noprompt dir1 dir2

请注意,这还会删除与dir1同一目录中其他文件重复的文件。

在具有 GNU 工具的系统上,dir1如果您自己编写脚本,则可以通过删除重复项来解决此问题:

#!/bin/sh

dir1=somedir
dir2=someotherdir

sums1=$(mktemp)
sums2=$(mktemp)

# Remove temporary files when done.
trap 'rm -f "$sums1" "$sums2"' EXIT

# Calculate checksums for first directory, extract only the checksums
# themselves and sort them (removing duplicate checksums).
find "$dir1" -type f -exec md5sum -z {} + |
cut -z -c -32 |
sort -z -u -o "$sums1"

# Calculate the checksums for the second directory, and sort them.
find "$dir2" -type f -exec md5sum -z {} + |
sort -z -o "$sums2"

# Join the files on the first column, extract the pathnames for the
# files in the second directory that have the same checksum as files in
# the first directory, and delete these files.
join -z "$sums1" "$sums2" |
cut -z -c 34- |
xargs -0 rm -f


# Optionally, delete empty directories in the second directory
# find "$dir2" -type d -empty -delete

上面的代码还尝试通过将路径名作为 nul 终止列表传递来确保正确处理任何有效的文件名。


bash上述脚本的较短变体:

#!/bin/bash

dir1=somedir
dir2=someotherdir

join -z \
    <(find "$dir1" -type f -exec md5sum -z {} + | cut -z -c -32 | sort -z -u)  \
    <(find "$dir2" -type f -exec md5sum -z {} + | sort -z) |
cut -z -c 34- |
xargs -0 rm -f

答案2

以下是比较所有文件的哈希值的方法。

方法一(推荐):

谢谢善行难陀建议使用join它来简化任务。您可以使用以下命令。请注意,如果任何文件的名称中包含空格,则此操作将不起作用。

# DIR1 is the main directory
# DIR2 is from where files will get deleted. Change the values accordingly
DIR1="$PWD"
DIR2="$HOME"

find $DIR1 -type f | xargs md5sum 2>/dev/null | sort > /tmp/m1
find $DIR2 -type f | xargs md5sum 2>/dev/null | sort > /tmp/m2

join /tmp/m1 /tmp/m2 > /tmp/m3
cat /tmp/m3 | cut -d ' ' -f3 | xargs rm -f

# To delete empty directories
find $DIR2 -type d -empty -delete

方法二:

这里我们只是重复计算两个目录中所有文件的哈希值,如果相同则删除该文件。

# DIR1 is the main directory
# DIR2 is from where files will get deleted.
DIR1="$PWD"
DIR2="$HOME"

# Take a file from $DIR1 and check for it in $DIR2
for i in $DIR1/*; do
    HASH=$(md5sum $i 2>/dev/null | cut -d ' ' -f1 )
    if [ "$HASH" ]; then
        for j in $DIR2/*; do
            HASH2=$(md5sum $j | cut -d ' ' -f1)
            if [ "$HASH" = "$HASH2" ]; then
                # Delete files from $DIR2
                rm "$j"
            fi
        done
    fi
done

相关内容