搜索类似的重复文件名(与文件名末尾的日期戳不同)

时间:2016-02-01 14:14:45

标签: linux bash duplicates filenames

我有类似(几乎相同)的问题,如(Keep latest file and delete all other)  除了我的文件列表不同,我不知道Python(尝试用Bash做)

目录包含这样的文件,例如:

mysql-2016-01-24/     *<--  dirname*
    adsoglasi-2016-01-24-05.35.gz
    adsoglasi-2016-01-24-09.35.gz
    adsoglasi-2016-01-24-13.35.gz
    adsoglasi-2016-01-24-17.35.gz
    adsoglasi-2016-01-24-21.35.gz
    ehoplit-2016-01-24-05.35.gz
    ehoplit-2016-01-24-09.35.gz
    ehoplit-2016-01-24-13.35.gz
    ehoplit-2016-01-24-17.35.gz
    ehoplit-2016-01-24-21.35.gz
    posavje-2016-01-24-05.35.gz
    posavje-2016-01-24-09.35.gz
    posavje-2016-01-24-13.35.gz
    posavje-2016-01-24-17.35.gz
    posavje-2016-01-24-21.35.gz
    export-mysql-baze-2016-01-24-05.35.log
    export-mysql-baze-2016-01-24-09.35.log
    export-mysql-baze-2016-01-24-13.35.log
    export-mysql-baze-2016-01-24-17.35.log
    export-mysql-baze-2016-01-24-21.35.log
    flora-2016-01-24-05.35.gz
    flora-2016-01-24-09.35.gz
    flora-2016-01-24-13.35.gz
    flora-2016-01-24-17.35.gz
    flora-2016-01-24-21.35.gz
    karcher-2016-01-24-05.35.gz
    karcher-2016-01-24-09.35.gz
    karcher-2016-01-24-13.35.gz
    karcher-2016-01-24-17.35.gz
    karcher-2016-01-24-21.35.gz
    knjigarna-2016-01-24-05.35.gz
    knjigarna-2016-01-24-09.35.gz
    knjigarna-2016-01-24-13.35.gz
    knjigarna-2016-01-24-17.35.gz
    knjigarna-2016-01-24-21.35.gz
    mysql-2016-01-24-05.35.gz
    mysql-2016-01-24-09.35.gz
    mysql-2016-01-24-13.35.gz
    mysql-2016-01-24-17.35.gz
    mysql-2016-01-24-21.35.gz
    mysqlshow_grants-2016-01-24-05.36.49.gz
    mysqlshow_grants-2016-01-24-09.36.50.gz
    mysqlshow_grants-2016-01-24-13.36.48.gz
    mysqlshow_grants-2016-01-24-17.36.48.gz
    mysqlshow_grants-2016-01-24-21.36.49.gz
    pohistvo-2016-01-24-05.35.gz
    pohistvo-2016-01-24-09.35.gz
    pohistvo-2016-01-24-13.35.gz
    pohistvo-2016-01-24-17.35.gz
    pohistvo-2016-01-24-21.35.gz
    akord-2016-01-24-05.36.gz
    akord-2016-01-24-09.36.gz
    akord-2016-01-24-13.36.gz
    akord-2016-01-24-17.36.gz
    akord-2016-01-24-21.36.gz
    ekomprof-2016-01-24-05.36.gz
    ekomprof-2016-01-24-09.36.gz
    ekomprof-2016-01-24-13.36.gz
    ekomprof-2016-01-24-17.36.gz
    ekomprof-2016-01-24-21.36.gz
    gume-2016-01-24-05.36.gz
    gume-2016-01-24-09.36.gz
    gume-2016-01-24-13.36.gz
    gume-2016-01-24-17.36.gz
    gume-2016-01-24-21.36.gz
    orchestra_test-2016-01-24-05.36.gz
    orchestra_test-2016-01-24-09.36.gz
    orchestra_test-2016-01-24-13.36.gz
    orchestra_test-2016-01-24-17.36.gz
    orchestra_test-2016-01-24-21.36.gz

这是每天在单独的目录中完成的

mysql-2015-11-16/
mysql-2015-11-19/

-- || --

mysql-2016-01-18/
mysql-2016-01-19/
mysql-2016-01-20/
mysql-2016-01-21/
mysql-2016-01-22/
mysql-2016-01-23/
mysql-2016-01-24/
...

我正在寻找的目录将仅保留最新的日期和时间文件名,并且每个&#34;重复&#34;删除了类似的文件(它们使空间混乱),

我希望获得的输出:

mysql-2015-11-16/
                adsoglasi-2016-01-16-21.35.gz
                ehoplit-2016-01-16-21.35.gz
                posavje-2016-01-16-21.35.gz
                export-mysql-baze-2016-01-16-21.35.log
                flora-2016-01-16-21.35.gz
                karcher-2016-01-16-21.35.gz
                knjigarna-2016-01-16-21.35.gz
                mysql-2016-01-16-21.35.gz
                mysqlshow_grants-2016-01-16-21.36.49.gz
                pohistvo-2016-01-16-21.35.gz
                akord-2016-01-16-21.36.gz
                ekomprof-2016-01-16-21.36.gz
                gume-2016-01-16-21.36.gz
                orchestra_test-2016-01-16-21.36.gz
-- || --
mysql-2015-11-19/
                ....filenames with date ...2015-11-19... 
-- || --
mysql-2016-01-24/
                adsoglasi-2016-01-24-21.35.gz
                ehoplit-2016-01-24-21.35.gz
                posavje-2016-01-24-21.35.gz
                export-mysql-baze-2016-01-24-21.35.log
                flora-2016-01-24-21.35.gz
                karcher-2016-01-24-21.35.gz
                knjigarna-2016-01-24-21.35.gz
                mysql-2016-01-24-21.35.gz
                mysqlshow_grants-2016-01-24-21.36.49.gz
                pohistvo-2016-01-24-21.35.gz
                akord-2016-01-24-21.36.gz
                ekomprof-2016-01-24-21.36.gz
                gume-2016-01-24-21.36.gz
                orchestra_test-2016-01-24-21.36.gz

...现在找到一个更好的清单: - )

但是因为我没有使用某些&#34;工具&#34;像fdupes或类似的,我向专业人士寻求帮助。

TY, 最诚挚的问候。

2 个答案:

答案 0 :(得分:0)

幸运的是,这些日期标记采用ISO表示法,年月日,因此简单的ascii排序,也是日期排序。这使得这些事情变得容易。只依靠“ls”排序以正确的顺序获取文件,然后我们可以读取,比较日期之前的部分,如果前一个具有相同的基本部分,那么我们可以删除前一个。

假设这些文件夹中的所有文件确实具有该模式(特别是如果基本名称部分中不存在“dash-year-dash”模式 - 如果不确定,则必须使正则表达式更长一定要只匹配日期+序列+扩展名)。首先让我们看看将删除的内容,在这样的文件夹中执行:

ls | perl -nle '($b)=m{^(.*?)-2\d\d\d-.*}; print $fn if $fn && $b eq $p_b; $p_b=$b; $fn=$_;'

要真正删除这些文件,只需将“print”替换为“unlink”语句:

ls | perl -nle '($b)=m{^(.*?)-2\d\d\d-.*}; unlink $fn if $fn && $b eq $p_b; $p_b=$b; $fn=$_;'

要在所有这些文件夹上执行此操作,请cd到包含所有mysql-YYYY-MM-DD文件夹的父文件夹中:

for d in mysql*; do (cd $d;
    ls | perl -nle '($b)=m{^(.*?)-2\d\d\d-.*}; unlink $fn if $fn && $b eq $p_b; $p_b=$b; $fn=$_;'
); done

- 编辑 -

显然你有别名“ls”到“ls -l”。完全避免“ls”:

find . -maxdepth 1 -type f -print0 | sort | perl -0x00 -ne '($b)=m{^(.*?)-2\d\d\d-.*}; unlink $fn if $fn && $b eq $p_b; $p_b=$b; $fn=$_;'

但是当你甚至不确定你输入的所有文件都没有达到预期的格式时,那么也许你应该更具体地处理要处理的文件以及要排除的文件。现在该模式假定文件名中必须出现模式“-2 \ d \ d \ d-”(短划线,数字2,后跟3个数字,后跟短划线),该部分将启动日期戳。 / p>

E.g。匹配格式'-YYYY-MM-DD-'的完整日期(包括之前的破折号),以及尽可能到名称的末尾;

find . -maxdepth 1 -type f -print0 | sort | 
perl -0x00 -ne '($b)=m{^(.*)-2\d\d\d-\d\d-\d\d-.*}; unlink $fn if $fn && $b eq $p_b; $p_b=$b; $fn=$_;'

在该日期之前的任何事情都被视为比较的基础;该日期和之后的东西被认为是“模糊”部分,仅用于排序。

答案 1 :(得分:0)

@PBI:

不幸的是,这个

ls | perl -nle '($b)=m{^(.*?)-2\d\d\d-.*}; print $fn if $fn && $b eq $p_b; $p_b=$b; $fn=$_;' 

不会产生任何想要的输出(这是实际输出):

total 569356
drwxr-xr-x  2 root   root      4096 Jan 17 21:36 ./

“ls”输出:

--  || --
-rw-r--r--  1 root   root  22247827 Jan 17 05:35 akord-2016-01-17-05.35.gz
-rw-r--r--  1 root   root  22266602 Jan 17 09:35 akord-2016-01-17-09.35.gz
-rw-r--r--  1 root   root  22287951 Jan 17 13:35 akord-2016-01-17-13.35.gz
-rw-r--r--  1 root   root  22248103 Jan 17 17:35 akord-2016-01-17-17.35.gz
--  || --

在文件大小和所有者的行的开头打印出来,这会混淆Perl以对文件名进行排序。

但是......“find”命令可以很好地打印出预期的内容:

find ./ -type f -printf "%f\n" | sort | perl -nle '($b)=m{^(.*?)-2\d\d\d-.*}; print $fn if $fn && $b eq $p_b; $p_b=$b; $fn=$_;'

adsoglasi-2015-12-17-05.35.gz
adsoglasi-2015-12-17-09.35.gz
adsoglasi-2015-12-17-13.35.gz
adsoglasi-2015-12-17-17.35.gz

它应该打印出来的是什么,而不是“来源”列表:

adsoglasi-2015-12-17-05.35.gz
adsoglasi-2015-12-17-09.35.gz
adsoglasi-2015-12-17-13.35.gz
adsoglasi-2015-12-17-17.35.gz
adsoglasi-2015-12-17-21.35.gz

现在省略了最后一个文件(yaaay :-),因此它生成了要删除的文件列表!非常好!

重要提示!

“find ...”没有“ sort ”也没有输出任何有用的东西,除了一个文件名保留在Perl“缓冲区”中(据我所知)