bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html


要比较两个文件的内容是否完全一致,可以简单地使用diff命令。例如:

diff file1 file2 &>/dev/null;echo $?

但是diff命令只能给定两个文件参数,因此无法一次性比较多个文件(目录也被当作文件),而且diff比较非文本类文件或者极大的文件时效率极低。

这时可以使用md5sum来实现,相比diff的逐行比较,md5sum的速度快的多的多。

md5sum的使用方法见:Linux中文件MD5校验

但md5sum只能通过查看md5值来间接比较文件是否相同,要实现批量自动比较,则需要写成循环。脚本如下:

#!/bin/bash
###########################################################
# description: compare many files one time #
# author : 骏马金龙 #
# blog : http://www.cnblogs.com/f-ck-need-u/ #
########################################################### # filename: md5.sh
# Usage: $ file1 file2 file3 ... IFS=$'\n'
declare -A md5_array # If use while read loop, the array in while statement will
# auto set to null after the loop, so i use for statement
# instead the while, and so, i modify the variable IFS to
# $'\n'. # md5sum format: MD5 /path/to/file
# such as:80748c3a55b726226ad51a4bafa1c4aa /etc/fstab
for line in `md5sum "$@"`
do
index=${line%% *}
file=${line##* }
md5_array[$index]="$file ${md5_array[$index]}"
done # Traverse the md5_array
for i in ${!md5_array[@]}
do
echo -e "the same file with md5: $i\n--------------\n`echo ${md5_array[$i]}|tr ' ' '\n'`\n"
done

为了测试该脚本,先复制几个文件,并修改其中几个文件的内容,例如:

[root@xuexi ~]# for i in `seq -s' ' `;do cp -a /etc/fstab /tmp/fs$i;done
[root@xuexi ~]# echo ha >>/tmp/fs4
[root@xuexi ~]# echo haha >>/tmp/fs5

现在,/tmp目录下有6个文件fs1、fs2、fs3、fs4、fs5和fs6,其中fs4和fs5被修改,剩余4个文件内容完全相同。

[root@xuexi tmp]# ./md5.sh /tmp/fs[1-6]
the same file with md5: a612cd5d162e4620b442b0ff3474bf98
--------------------------
/tmp/fs6
/tmp/fs3
/tmp/fs2
/tmp/fs1 the same file with md5: 80748c3a55b726226ad51a4bafa1c4aa
--------------------------
/tmp/fs4 the same file with md5: 30dd43dba10521c1e94267bbd117877b
--------------------------
/tmp/fs5

更具通用性地比较方法:比较多个目录下的同名文件。

[root@xuexi tmp]# find /tmp -type f -name "fs[0-9]" -print0 | xargs -0 ./md5.sh
the same file with md5:a612cd5d162e4620b442b0ff3474bf98
--------------------------
/tmp/fs6
/tmp/fs3
/tmp/fs2
/tmp/fs1 the same file with md5:80748c3a55b726226ad51a4bafa1c4aa
--------------------------
/tmp/fs4 the same file with md5:30dd43dba10521c1e94267bbd117877b
--------------------------
/tmp/fs5

脚本说明:

(1).md5sum计算的结果格式为"MD5 /path/to/file",因此要在结果中既输出MD5值,又输出相同MD5对应的文件,考虑使用数组。

(2).一开始的时候我使用while循环,从标准输入中读取每个文件md5sum的结果。语句如下:

md5sum "$@" | while read index file;do
md5_array[$index]="$file ${md5_array[$index]}"
done

但由于管道使得while语句在子shell中执行,于是while中赋值的数组md5_array在循环结束时将失效。所以可改写为:

while read index file;do
md5_array[$index]="$file ${md5_array[$index]}"
done <<<"$(md5sum "$@")"

不过我最终还是使用了更繁琐的for循环:

IFS=$'\n'
for line in `md5sum "$@"`
do
index=${line%% *}
file=${line##* }
md5_array[$index]="$file ${md5_array[$index]}"
done

但md5sum的每行结果中有两列,而for循环采用默认的IFS会将这两列分割为两个值,因此还修改了IFS变量的值为$'\n',使得一行赋值一次变量。

(3).index和file变量是为了将md5sum的每一行结果拆分成两个变量,MD5部分作为数组的index,file作为数组变量值的一部分。因此,数组赋值语句为:

md5_array[$index]="$file ${md5_array[$index]}"

(4).数组赋值完成后,开始遍历数组。遍历的方法有多种。我采用的是遍历数组的index列表,即每行的MD5值。

# Traverse the md5_array
for i in ${!md5_array[@]}
do
echo -e "the same file with md5: $i\n--------------\n`echo ${md5_array[$i]}|tr ' ' '\n'`\n"
done

shell脚本示例:批量比较多个文件的内容是否相同的更多相关文章

  1. (转)通过shell脚本实现批量添加用户和设置随机密码以及生产环境如何批量添加

    通过shell脚本实现批量添加用户和设置随机密码以及生产环境如何批量添加 原文:http://www.21yunwei.com/archives/4773 有一个朋友问我如何批量创建用户和设置密码 , ...

  2. shell脚本:批量修改文件名

    参考链接1:shell脚本:批量修改文件名(删除文件名中字符) 参考链接2:linux shell 字符串操作详解 (长度,读取,替换,截取,连接,对比,删除,位置 ) 参考链接3:每天一个linux ...

  3. PHP批量清空删除指定文件夹内容

    PHP批量清空删除指定文件夹内容: cleancache.php <?php // 清文件缓存 $dirs = array( realpath(dirname(__FILE__) . '/../ ...

  4. shell脚本中使用echo显示带颜色的内容

    shell脚本中使用echo显示带颜色的内容,需要使用参数-e 格式如下: echo -e "\033[字背景颜色;文字颜色m字符串\033[0m" 例如: echo -e &qu ...

  5. 使用shell脚本分析Nagios的status.dat文件

    前言 Nagios的安装和配置以及批量添加监控服务器在我前面的文章中已经讲的很详细了. 我们知道,Nagios的网页控制页面(一般为http://nagio.domain.com/nagios)里可以 ...

  6. shell脚本获取文件名、路径名、文件类型

    1. 从字符串获取指定内容 从字符串中提取特定的信息,常用于获取文件名.文件类型.所在路径等. 1.1 获取字符串信息 用指定的方式(PATTERN)从字符串(PARAMETERS)中移除内容 &qu ...

  7. shell脚本仅列出当前目录下的文件及文件夹

    #!/bin/bash function ergodic(){ ` # do # "/"$file ] # then # ergodic $"/"$file # ...

  8. 利用python和shell脚本生成train.txt的标签文件

    1. 用shell脚本生成带绝对路径的train.txt 例如我要生成如下形式的带标签的文件,如图:(如有两个标签:0 和 1) shell脚本如下: 这样标签0写入了train.txt # /usr ...

  9. 【shell脚本】批量修改扩展名===modifyExtension.sh

    前提:需切换到需要批量修改扩展名的目录下,运行脚本 [root@VM_0_10_centos shellScript]# cat modifyExtension.sh #!/bin/bash # 编写 ...

随机推荐

  1. shell搭建CentOS_7基础环境

    #!/bin/bash#Auth:Darius#CentOS_7配置实验环境eno=`ifconfig|awk '{print $1}'|head -1|awk -F ":" '{ ...

  2. pdf流文件的展示、下载、打印;html转为pdf

    背景:合同(后台返回pdf流文件)展示.下载.打印,基于angular4 场景区分: 1.checkout页面 —— post接口,入参为offering.shippingInfo.invoice等( ...

  3. CentOS MariaDB 安装和配置

    sudo vi /etc/yum.repos.d/mariadb.repo # MariaDB 10.1 CentOS repository list - created 2017-03-23 13: ...

  4. vue watch高级用法

    watch是vue组件最常用,最重要的功能之一,我们都知道它最基本的特性就是监听的data对象里的属性变化了,watch就会自动执行. 那它还有什么骚操作呢?下面我带大家看看,菜鸟一枚,如有错误欢迎指 ...

  5. HDU1262-寻找素数对

    //#include<bits/stdc++.h> #include<map> #include<cstdio> #include<string> #i ...

  6. 剑指C++面试

    传闻公司老总欠下巨款,带着小姨子跑路了~  树倒猢狲散,接下来要好好准备面试,以期找到一份满意的工作. 面试准备分下面几个方面进行,形成面试系列文章,文章内容以问答的方式呈现. 1.C++语言基础 传 ...

  7. metools,个人工具站点分享

    需要[加密/解密][编码/解码][生成二维码]的时候不用再进百度点广告~ 也不需要去收藏夹找网址~ 我的目的大概就是如此. 项目地址:https://github.com/yimogit/metool ...

  8. 从零开始单排学设计模式「策略模式」黑铁 II

    阅读本文大概需要 1.7 分钟. 本篇是设计模式系列的第三篇,虽然之前也写过相应的文章,但是因为种种原因后来断掉了,而且发现之前写的内容也很渣,不够系统.所以现在打算重写,加上距离现在也有一段时间了, ...

  9. Redis学习笔记之Redis基本数据结构

    Redis基础数据结构 Redis有5种基本数据结构:String(字符串).list(列表).set(集合).hash(哈希).zset(有序集合) 字符串string 字符串类型是Redis的va ...

  10. 消除浏览器对input的自动填充

    在做登录相关的页面时,常遇到这样的现象,浏览器input的自动填充行为. 原因 设置 input 的 type 属性为 password 后,当页面进行过提交,并且允许浏览器记住密码后,那么再次加载该 ...