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

发布于 2024-12-06 08:13:23 字数 291 浏览 0 评论 0原文

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

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

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

我想如果这个问题可以解决一个目录,例如 dir a,那么我可以在它周围包裹一个 for 循环吗?

for f in *; do
???
done

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

I have a file structure like so

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

where within each dir, some files have the same file size, and I would like to delete those.

I guess if the problem could be solved for one dir e.g. dir a, then I could wrap a for-loop around it?

for f in *; do
???
done

But how do I find files with same size?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

枫林﹌晚霞¤ 2024-12-13 08:13:23
 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 命令test

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 的评论进行更新

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

command:

 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];}'

test:

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$
 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];}'

this will only check files, no directories.

$5 is the size of ls command

test:

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$ 

update based on Michał Šrajer 's comment:

Now filenames with spaces are also supported

command:

 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];}'

test:

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$
初见 2024-12-13 08:13:23

使用“带空格的文件名”的解决方案(基于 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

Solution working with "file names with spaces" (based on Kent (+1) and awiebe (+1) posts):

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

to make it remove duplicates, remove echo from xargs.

蓝海似她心 2024-12-13 08:13:23

如果您需要文件的大小,请使用以下代码:

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

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

在该 for 循环中将 for 循环嵌套到结构中的每个项目(不包括当前项目)到当前项目。

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

对此文件的内容执行 rm。

Here is code if you need the size of a file:

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

Then use a for loop to get the first item in your structure,
Store the size of that file in a variable.

Nest a for loop in that for loop to each item in your structure(excluding the current item) to the current item.

Route all the names of identical files into a text file to ensure you have written you script correctly(insteed of executing rm immediately) .

Execute rm on the contents of this file.

未蓝澄海的烟 2024-12-13 08:13:23

简单的 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

Plain bash solution

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
桃扇骨 2024-12-13 08:13:23

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

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

Based on the accepted answer, the following provides a list of all the files of the same size in the current directory (so you can choose which one to keep), sorted by size:

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

To determine if the files are actually the same, not just the contain the same number of bytes, do an shasum or md5sum on each file:

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
小情绪 2024-12-13 08:13:23

看来您真正想要的是重复文件查找器

Looks like what you really want is a duplicate file finder?

超可爱的懒熊 2024-12-13 08:13:23

听起来这个问题已经以几种不同的方式得到了多次回答,所以我可能已经死了,但这里是...

find DIR_TO_RUN_ON -size SIZE_OF_FILE_TO_MATCH -exec rm {} \;

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

It sounds like this has been answered several times and in several different ways, so I may be beating a dead horse but here goes...

find DIR_TO_RUN_ON -size SIZE_OF_FILE_TO_MATCH -exec rm {} \;

find is an awesome command and I highly recommend reading its manpage.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文