linux - 比较文件内容并删除较短的内容
问题描述
我有数千个 .txt 文件。我想删除其中一些。有些文件是相似的——内容相同,但一个较长,我需要删除较短的一个。所有文件都放在一个文件夹中。
关于这些文件唯一知道的是一个文件可以有内容
ABCDEFGH
和另一个
ABCDEF
但不是
XYZ
我需要做的是删除ABCDEF
具有类似较长文件的ABCDEFGH
文件。我期望 n*(n-1) 比较。假设文件应该以二进制形式进行比较。bash(或通常是 Linux)中是否有一个脚本可以为我做到这一点?如果我必须这样做,我会编写一个 C# 控制台应用程序来比较所有文件并删除相似但较短的文件,但我认为在 bash 脚本中(或在 Linux 上)会更容易和更快。允许使用外部工具。如果文件具有相同的内容并且长度相同 - 文件之一必须保留在文件夹中。有可能会有3个或更多文件(具有相同的内容)和(相同的长度或不同的长度)。
解决方案
任何对这种 Perl 脚本感兴趣的人都会很高兴。我假设我们在当前文件夹中有带有 *.txt 文件的脚本。如果文件与其他文件相同但更长或更短,因此其中一个文件中有一些数据使其更长但与前面部分没有区别,则将删除较短的文件。对于 1.3MB 和 1300 个文件,Cygwin Perl 用了不到 2 分钟的时间来浏览所有文件。文件逐行比较。下面的脚本:
#!/usr/bin/env perl
use strict;
use warnings;
my @files = <*.txt>;
my @del;
my $diff;
foreach my $file1 (@files) {
foreach my $file2 (@files) {
if ($file1 eq $file2) {
last;
}
open my $fh1, $file1 or die "can't open $file1: $!";
open my $fh2, $file2 or die "can't open $file2: $!";
print "Comparing $file1 and $file2...";
my $line1;
my $line2;
$diff=0;
while($line1 = <$fh1>) {
$line2 = <$fh2>;
if ($line1 ne $line2) {
print "different!\n";
$diff=1;
last;
}
}
if ($diff == 0) {
print "the same till end of one files!\n";
if (-s $file1 >= -s $file2)
{
push @del, $file2;
}
if (-s $file1 < -s $file2)
{
push @del, $file1;
}
}
close($fh1);
close($fh2);
}
}
foreach my $file (@del) {
print "Removing $file\n";
unlink $file;
}
请注意,文件的编码和行尾可能不同,因此所有文件,例如,都应该是 UTF-8 编码并且行尾应该是相同的 - LF。
推荐阅读
- reactjs - 你应该从 redux slice reducer 中返回什么?
- ansible - 如何运行多个剧本,每个剧本都有一个调查?
- ckeditor - 如何在 CKEditor 5 中禁用 Shift+Enter
- ios - 如何调整圆圈的大小以动态调整到任何 iPhone 的宽度和高度?
- java - 如何以 3D 排列方式打印不同尺寸的矩阵?
- mongodb - 如何在 mongoDB 中通过 _id 将两个数组合并为一个并设置为特定字段?
- vector - 我正在尝试使用堆栈打印数字序列的反转。堆栈是使用 Vector 实现的。但我得到分段错误
- javascript - 为什么在 firebase.auth().createUserWithEmailAndPassword() 调用后 useRef() 挂钩设置为 null?
- mysql - Nodejs - MySQL - 如何解决此脚本中的“连接太多”错误?
- javascript - 对象可能是“未定义的”。从 typescript 3.7.2 升级到 3.8 后