linux文本排序、交集、差集,查找并删除重复文件脚本、comm命令

comm 命令

comm命令可用于两个文件之间的比较。通过参数调整输出,可以执行交集、求差以及差集操作。

- 交集:打印出两个文件所有共同的行。

- 求差:打印出指定文件所包含的互不相同的那些行。

- 差集:打印出包含在文件A中,但不包含在其他指定文件中的那些行。

需要注意的是,comm必须使用经过排序的文件作为输入。在linux中可以使用sort命令实现排序。

comm实战

建立两个文本文件输入以下内容:


cat A.txt

apple

orange

gold

silver

steel

iron

cat B.txt

orange

gold

cookies

carrot

此时两个文件内的文本是乱序的,使用sort进行排序。

sort [option] [file] 参数 -o 要输出的文件。


sort A.txt -o A.txt;

sort B.txt -o B.txt;

(1) 首先执行不带任何选项的comm:


$ comm A.txt B.txt

apple

    carrot

    cookies

        gold

iron

        orange

silver

steal

输出的第一列包含中在A.txt中的行,第二列包含只在B.txt中出现的行,第三列包含同时包含两文件中相同的行。各列使用\t分隔。

(2) 为了打印两个文件的交集,我们需要删除第一列和第二列,只打印第三列:


$ comm A.txt B.txt -1 -2

gold

orange

(3) 打印出两个文件中不相同的行:


$ comm a.txt b.txt -3


apple

    carrot

    cookies

iron

silver

steal

(4) 为了提高输出结果的可用性,需要删除空白字段,将两列合并成一列:

借助sed命令格式化输出。

sed - stream editor for filtering and transforming text 字符流编辑


$ comm a.txt b.txt -3 | sed 's/^\t//'

apple

carrot

cookies

iron

silver

steal

sed 命令解释: sed命令通过管道获取comm的输出。它删除行首的\t字符。sed中的s表示替换substitute。/^\t/匹配行前的\t(^是行首标记).//是用来替换行首的/t的字符串。如此一来,就可以删除所有行首的\t.

查找并删除重复文件

这里重复文件指文本内容相同的文件,我们可以借助校验和md5sum命令进行校验。

(1) 创建测试文件


$ echo "hello" > test;

$ cp test test_cp1;

$ cp test test_cp1;

$ echo "next" > other;

(2) 编写脚本文件


# !/bin/bash

# 文件名: remove_dupliates.sh

# 描述:查找当前目录下重复文件,删除



ls -lS --time-style=long-iso | awk 'BEGIN {

    getline;getline;

    name1=$8;size=$5

}

{

    name2=$8;

    if(size==$5){

        "md5sum "name1 | getline; csum1=$1;

        "md5sum "name2 | getline; csum2=$1;

        if(csum1==csum2){

            print name1;print name2

        } 

    };

    size=$5; name1=name2;

}' | sort -u > duplicate_files



cat duplicate_files | xargs -I {} md5sum {} | sort | uniq -w 32 | awk '{ print "^"$2"$" }' | sort -u > duplicate_sample

echo Removing...

comm duplicate_files duplicate_sample -2 -3 | tee /dev/stderr | xargs rm 

echo Removed duplicated files successfully.

此shell工作原理。ls -lS 对当前目录所有文件按照文件大小进行排序,并列出文件的详细信息。awk读取ls -lS的输出,对行列进行比较,找出重复文件。

执行逻辑:

  • 将文件依据大小排序并列出,这样大小相近的文件会排列在一起。识别大小相同的文件是我们查找重复文件的第一步。接下来,计算这些文件的校验和。如果校验和相同,那么这些文件就是重复文件,将被删除。

  • 在从文件中读取文本行之前,首先要执行awk(awk是一个强大的文本分析工具)的BEGIN{}语句块.读取文本的工作在{}语句中进行,读取并处理的忣的行后,执行END{}语句块。

    使用$1,$2,$3...$n中获取命令输出中的每一列。我们将文件的md5sum保存在变量csum1和csum2中。变量name1和name2保存文件列表中位置连续的文件名。如果两个文件的校验和相同,那它们肯定是重复文件,其文件名会被打印出来。

你可能感兴趣的:(linux)