Scripting 在linux中以编程方式比较文件大小

Scripting 在linux中以编程方式比较文件大小,scripting,Scripting,我有两个版本的非常大和复杂的目录结构,有成千上万个单独的文件,我想寻找从一个版本到另一个版本的重大文件更改 每个文件都有一些小的变化。例如,您可能有一个名为intro.txt的文件,其中包含 [Build 1057由Mike 12:00完成](版本1) [Build 1065由Mike 18:10完成](版本2) 我不关心这样的更改,因为它们不包含有用的信息。我也不在乎拼写错误的更正或添加一两个单词 我真正想做的是找出哪些文件以更大的方式发生了更改。他们可能改变的一种方式是添加了很多额外的内容,

我有两个版本的非常大和复杂的目录结构,有成千上万个单独的文件,我想寻找从一个版本到另一个版本的重大文件更改

每个文件都有一些小的变化。例如,您可能有一个名为intro.txt的文件,其中包含

[Build 1057由Mike 12:00完成](版本1)

[Build 1065由Mike 18:10完成](版本2)

我不关心这样的更改,因为它们不包含有用的信息。我也不在乎拼写错误的更正或添加一两个单词

我真正想做的是找出哪些文件以更大的方式发生了更改。他们可能改变的一种方式是添加了很多额外的内容,这会增加文件大小——这就是我感兴趣的改变

那么,您如何递归地解析目录,查找从一个版本到下一个版本增加(或减少)了一定数量的文件呢


我正在运行linux,但几乎任何语言都可以

在python中,您希望从模块开始

比较目录-然后打印出一方或另一方缺少的文件(和)

然后,您需要进行更详细的比较-使用
os.stat
找出大小,如果差异太大,则打印文件名


最后,您需要递归到公共子目录中

我会执行
diff-r-b FOLDER1 FOLDER2
以获取已更改文件的列表,然后处理该列表(使用bash脚本就足够了),只需检查每个文件的大小差异,如果差异超过阈值,则打印文件名

diff
-b
选项用于简短输出,它只为发现的每个差异打印一行,而不打印每行更改

-r
通常用于递归比较两个目录。

在bash中:

before_dir=foo.old
after_dir=foo.new
interesting_size=10
for file in `find $before_dir -type f`; do
    diff_size=$(diff -u "$file" "$after_dir$(echo $file | sed "s,$before_dir,,")" | wc -l)
    if [ $diff_size -ge $interesting_size ]; then
        echo $file;
    fi;
done

CPAN上有几个模块提供了这一点。例如

文件::DirCompare看起来最有希望

 use File::DirCompare;

 File::DirCompare->compare('dirA', 'dirB', sub {
     my ($a, $b) = @_;

     ... callback runs on different or missing files   ...
     ... so perform extra checks on files $a & $b here ...

 });
因此,显示差异超过规定字节数的文件的一个示例是

File::DirCompare->compare('dirA', 'dirB', size_diff_by_more_than(1024) );

sub size_diff_by_more_than {
    my $this = shift;

    return sub {
        my @files = grep { $_ } @_;

        if ( @files == 2 ) {
            # get the two file sizes and report if more than $this
            my @sizes = sort { $a <=> $b } map { (stat)[7] } @files;
            print "Different by more than $this bytes: $files[1]\n"
                if $sizes[1] - $sizes[0] > $this
        }
        else {
            print "Only: $files[0]\n";
        }
    };
}
File::DirCompare->compare('dirA','dirB',size_diff_比(1024)大);
子尺寸差异比{
我的$this=shift;
返回接头{
my@files=grep{$}@;
如果(@files==2){
#获取两个文件大小,如果超过$this,则报告
my@size=sort{$a$b}map{(stat)[7]}@文件;
打印“差异超过$this字节:$files[1]\n”
如果$size[1]-$size[0]>$this
}
否则{
打印“仅:$files[0]\n”;
}
};
}

您可以生成两个目录的差异,并在其上使用实用程序。Diffstat报告更改文件的统计信息:添加、删除或修改了多少行。我想这将为您提供更多信息,而不仅仅是比较文件大小。

关于确定两个文件之间的差异量:

最好运行两个文件的diff,并将diff输出的长度与文件的总体大小联系起来


这(除了文件大小比较之外)将捕获文件中有大量更改但总体文件大小没有显著更改的情况。这可能适用于您的用例,也可能不适用于您的用例

在C语言中,对文件调用stat

#include #include #include int main( int argc, char* argv[] ) { struct stat fileInfoA; struct stat fileInfoB; if( argc == 3 ) { stat( argv[1], &fileInfoA ); stat( argv[2], &fileInfoB ); // Now, you can use the following fields of stat to compare the files: // struct stat { // dev_t st_dev; /* ID of device containing file */ // ino_t st_ino; /* inode number */ // mode_t st_mode; /* protection */ // nlink_t st_nlink; /* number of hard links */ // uid_t st_uid; /* user ID of owner */ // gid_t st_gid; /* group ID of owner */ // dev_t st_rdev; /* device ID (if special file) */ // off_t st_size; /* total size, in bytes */ // blksize_t st_blksize; /* blocksize for filesystem I/O */ // blkcnt_t st_blocks; /* number of blocks allocated */ // time_t st_atime; /* time of last access */ // time_t st_mtime; /* time of last modification */ // time_t st_ctime; /* time of last status change */ // }; } #包括 #包括 #包括 int main(int argc,char*argv[]) { struct stat fileInfoA; struct stat fileInfoB; 如果(argc==3) { stat(argv[1],&fileInfoA); stat(argv[2],&fileInfoB); //现在,您可以使用stat的以下字段来比较文件: //结构统计{ //包含文件的设备的dev_t st_dev;/*ID*/ //ino_t st_ino;/*inode编号*/ //模式\u t st\u模式;/*保护*/ //nlink\u t st\u nlink;/*硬链接数*/ //uid\u t st\u uid;/*所有者的用户ID*/ //gid_t st_gid;/*所有者的组ID*/ //dev_t st_rdev;/*设备ID(如果是特殊文件)*/ //off_t st_size;/*总大小,以字节为单位*/ //blksize\u t st\u blksize;/*文件系统I/O的块大小*/ //blkcnt_t st_块;/*分配的块数*/ //time\u t st\u atime;/*上次访问的时间*/ //上次修改的时间*/ //time\u t st\u ctime;/*上次状态更改的时间*/ // }; }
现在,这对于比较单个文件很有用。要递归地比较目录中的文件,显然需要使用递归(或堆栈)。还需要opendir()和readdir()系统调用。

希望这足以让您开始学习。谢谢Doug-这看起来足够让您开始学习了。尽管我在语言上提供了自由范围,但我感觉第一个答案将引用Python:)