如何查找大小相同的文件?

时间:2011-09-24 20:12:30

标签: linux bash awk

我有一个像这样的文件结构

a/file1
a/file2
a/file3
a/...
b/file1
b/file2
b/file3
b/...
...

在每个目录中,某些文件具有相同的文件大小,我想删除它们。

我想如果问题可以解决一个目录,例如dir a,然后我可以在它周围换一个for循环?

for f in *; do
???
done

但是如何查找大小相同的文件?

7 个答案:

答案 0 :(得分:8)

 ls -l|grep '^-'|awk '{if(a[$5]){ a[$5]=a[$5]"\n"$NF; b[$5]++;} else a[$5]=$NF} END{for(x in b)print a[x];}'

这只会检查文件,没有目录。

$ 5是ls命令的大小

试验:

kent@ArchT60:/tmp/t$ ls -l
total 16
-rw-r--r-- 1 kent kent  51 Sep 24 22:23 a
-rw-r--r-- 1 kent kent 153 Sep 24 22:24 all
-rw-r--r-- 1 kent kent  51 Sep 24 22:23 b
-rw-r--r-- 1 kent kent  51 Sep 24 22:23 c
kent@ArchT60:/tmp/t$ ls -l|grep '^-'|awk '{if(a[$5]){ a[$5]=a[$5]"\n"$NF; b[$5]++;} else a[$5]=$NF} END{for(x in b)print a[x];}'
a
b
c
kent@ArchT60:/tmp/t$ 

根据MichałŠrajer的评论更新

现在也支持带空格的文件名

命令:

 ls -l|grep '^-'|awk '{ f=""; if(NF>9)for(i=9;i<=NF;i++)f=f?f" "$i:$i; else f=$9; 
        if(a[$5]){ a[$5]=a[$5]"\n"f; b[$5]++;} else a[$5]=f}END{for(x in b)print a[x];}'

试验:

kent@ArchT60:/tmp/t$ l
total 24
-rw-r--r-- 1 kent kent  51 Sep 24 22:23 a
-rw-r--r-- 1 kent kent 153 Sep 24 22:24 all
-rw-r--r-- 1 kent kent  51 Sep 24 22:23 b
-rw-r--r-- 1 kent kent  51 Sep 24 22:23 c
-rw-r--r-- 1 kent kent  51 Sep 24 22:40 x y

kent@ArchT60:/tmp/t$ ls -l|grep '^-'|awk '{ f=""
        if(NF>9)for(i=9;i<=NF;i++)f=f?f" "$i:$i; else f=$9; 
        if(a[$5]){ a[$5]=a[$5]"\n"f; b[$5]++;} else a[$5]=f} END{for(x in b)print a[x];}'
a
b
c
x y

kent@ArchT60:/tmp/t$

答案 1 :(得分:4)

解决方案使用“带空格的文件名”(基于Kent(+1)和awiebe(+1)帖子):

for FILE in *; do stat -c"%s/%n" "$FILE"; done | awk -F/ '{if ($1 in a)print $2; else a[$1]=1}' | xargs echo rm

要删除重复项,请从xargs中删除echo

答案 2 :(得分:3)

如果您需要文件大小,请输入以下代码:

FILESIZE=$(stat -c%s "$FILENAME")
echo "Size of $FILENAME = $FILESIZE bytes."

然后使用for循环获取结构中的第一个项目, 将该文件的大小存储在变量中。

将for循环嵌套到for结构中的每个项目(当前项目除外)到当前项目。

将相同文件的所有名称路由到文本文件中,以确保您已正确编写脚本(保证立即执行rm)。

对该文件的内容执行rm。

答案 3 :(得分:0)

看起来你真正想要的是duplicate file finder

答案 4 :(得分:0)

根据接受的答案,以下提供了当前目录中相同大小的所有文件的列表(因此您可以选择要保留的文件),按大小排序:

for FILE in *; do stat -c"%s/%n" "$FILE"; done | awk -F/ '{if ($1 in a)print a[$1]"\n"$2; else a[$1]=$2}' | sort -u | tr '\n' '\0' | xargs -0 ls -lS

要确定文件是否实际相同,而不仅仅是包含相同数量的字节,请在每个文件上执行shasummd5sum

for FILE in *; do stat -c"%s/%n" "$FILE"; done | awk -F/ '{if ($1 in a)print a[$1]"\n"$2; else a[$1]=$2}' | sort -u | tr '\n' '\0' | xargs -0 -n1 shasum

答案 5 :(得分:0)

普通bash解决方案

find -not -empty -type f -printf "%s\n" | 
sort -rn | uniq -d | 
xargs -I{} -n1 find -type f -size {}c -print0 | 
xargs -0 du | sort

答案 6 :(得分:-1)

听起来好像已经多次以不同的方式回答了这个问题,所以我可能会打败一匹死马,但这里有......

找到DIR_TO_RUN_ON -size SIZE_OF_FILE_TO_MATCH -exec rm {} \;

find是一个很棒的命令,我强烈建议阅读它的联机帮助页。