我在两个文件夹中有三个文件。这些文件被命名为 ,a.txt
并且b.txt
位于c.txt
和A
文件夹中B
。我用过一个应用程序完整文件迷你比较器它会比较文件夹并保存到日志到该A
文件夹。
该日志有一些文本如下:
Different: A=/sdcard/A/a.txt B=/sdcard/B/a.txt
Same: A=/sdcard/A/b.txt B=/sdcard/B/b.txt
Different: A=/sdcard/A/c.txt B=/sdcard/B/c.txt
我如何使用sed
和rm
/或其他命令来永久删除/删除“相同”文件。
答案1
你有
$ tree
.
|-- A
| |-- a.txt
| |-- b.txt
| `-- c.txt
`-- B
|-- a.txt
|-- b.txt
`-- c.txt
2 directories, 6 files
使用fdupes
:
$ fdupes -1 A B
A/b.txt B/b.txt
fdupes
根据文件内容检测重复项。该-1
标志使其在一行上输出每组重复项的文件名。在这里,它检测到b.txt
文件是相同的。
您可以使用fdupes
以下方法删除重复项:
$ fdupes --delete A B
[1] A/b.txt
[2] B/b.txt
Set 1 of 1, preserve files [1 - 2, all]: 1
[+] A/b.txt
[-] B/b.txt
它以交互方式询问要保留哪个文件(或保留两个文件)。我写的1
所以文件在被删除A/b.txt
时被保留。B/b.txt
fdupes
( )参见手册man fdupes
。如果您的系统上未安装它,请使用包管理器来安装它。也可以做成自动删除文件,无需交互提示,但这样运行时一定要小心。在运行可能删除文件的命令之前,请务必先备份数据。
请注意,fdupes
将始终保留至少一个重复项。如果您想删除所有重复项,那么您可能对fdupes
SuperUser 中类似问题的答案中提到的这个修补版本感兴趣:https://superuser.com/a/947770/96962(我没有测试过这个)。
我建议使用而不是解析您拥有的日志文件的原因fdupes
是嵌入在文本文档中的文件名很难正确解析。可能不会总是可能很困难(在这个特定的例子中,这很容易),但请注意,Unix 允许在文件和目录的名称中使用空格和换行符。这是技术上可能有一个名为
a.txt
Same: A=
名称中嵌入换行符。
答案2
和awk
:
awk -F'[:]' '/Same:/{print $0}' logfile | xargs -n1 | awk -F'=' '{print $2}' | xargs rm -rf
awk
在日志文件中查找包含关键字“Same:”的行,然后xargs
将变量和路径(即 A=***)整理为每行,然后awk
捕获绝对路径。在最后一步中,xargs
要求rm
删除路径。
需要注意的是,当xargs
要求rm
删除路径时,这肯定会删除文件。-I
可以添加标志来rm
提醒用户确认删除。
-在删除超过三个文件之前,或者递归删除时提示一次;比 -i 更少侵入性,同时仍然提供针对大多数错误的保护
或与grep
grep "Same:" logfile | grep -oP '/[^ ]*' | xargs rm -rf
第一个grep
查找包含关键字 的行Same
。
第二个grep
填充日志文件以删除除与关键字相关的路径之外的所有内容。最后,xargs
要求rm
删除路径。
答案3
您真的想删除所有相同的文件,还是只删除 n-1 个文件并保留一份副本?那么,为什么不呢
awk '/Same:/ {for (i=2; i<=NF; i++) {split ($i, T, "="); print "rm", T[2]}}' log
rm /sdcard/A/b.txt
rm /sdcard/B/b.txt
sh
当对结果满意时输入。如果您也想保留一份副本,请从 开始循环i=3
。
或者,另一种方法没有awk
:
echo rm $(md5sum path/to/files* | sort | uniq -Dw33 | cut -d" " -f3-)
rm file2 file4
echo
如果对结果满意,请删除。如果文件名称中包含空格,则需要采取额外的步骤。