2014-03-03 135 views
1

我有1个目录有很多pdf文件。 此文件由另一脚本重命名与新版本的渐进号文件生成的:(例子)bash命令/脚本删除较旧的文件版本

newyork_v1.pdf 
newyork_v2.pdf 
newyork_v3.pdf 
miami_v1.pdf 
miami_v2.pdf 
rome_v1.pdf 

的版本号是相对于文件的一些文件是一个版本1,有人在2版等像例子中那样。 有些文件保留在版本1中用于所有的生活,有些文件可能会增长到第10版。

在一个临时目录拷贝这个目录后,我想删除旧版本的所有文件,在本例中必须保持:

newyork_v3.pdf 
miami_v2.pdf 
rome_v1.pdf 

我尝试排序和删除LS和排序命令,但我做的没有得到想要的结果,我尝试:

ls | sort -k2 -t_ -n -r | tail -n +2 | xargs rm 

与此命令只停留rome_v1.pdf

命令或脚本都无所谓,谁能帮助我?

回答

4
for file in $(ls *.pdf | awk -F'_' '{print $1}' | sort -u) 
do 
    count=$(ls ${file}* | wc -l) 
    if [ ${count} -gt 1 ]; then 
     ls -rv ${file}* | tail -$(($count-1)) | xargs rm 
    fi 
done 
+0

它的作品!谢谢!!! – user3375339

+0

只是一些改进的答案:使用 首先进行的修改日期排序可能会失败,只需使用'ls'默认的排序顺序 第二次使用'ls -1'而不是'ls -l'它为你节省了'awk'管道 –

+0

@Mojooo - ls -1' – Amit

0

这个Perl脚本可以被用来过滤掉旧的文件名:

#!/usr/bin/perl 

use warnings; 
use strict; 

my %files; 
my @old_files; 
while (<DATA>) { 
    chomp; 
    my ($name, $version, undef) = split /_v|\./, $_; 
    if (!$files{$name}->{version}) { 
     $files{$name}->{version} = $version; 
     $files{$name}->{name} = $_; 
     next; 
    } 
    if ($files{$name}->{version} < $version) { 
     push @old_files, $files{$name}->{name}; 
     $files{$name}->{version} = $version; 
     $files{$name}->{name} = $_; 
    } 
} 

foreach my $file (@old_files) { 
    print "$file\n"; 
} 

__DATA__ 
newyork_v1.pdf 
newyork_v2.pdf 
newyork_v3.pdf 
miami_v1.pdf 
miami_v2.pdf 
rome_v1.pdf 
+0

谢谢,但我不能在此机器上:(安装perl – user3375339

+0

@ user3375339哦,这是不幸的 –

2

如果你可以使用GNU LS,你可以试试下面:

for p in $(ls -v *.pdf | cut -d_ -f1 | sort | uniq); do 
    ls -v $p* | head -n -1 | xargs -I{} rm {} 2>/dev/null 
done 

的-v GNU ls的标志将文件'自然'排序,即。你的情况:

miami_v1.pdf 
miami_v2.pdf 
newyork_v1.pdf 
newyork_v2.pdf 
newyork_v3.pdf 
newyork_v10.pdf #Added to show ls -v in action 
rome_v1.pdf 

然后,我们通过每个uniq的循环前缀并删除比前缀匹配的最后一个文件中的其他一切。

结果:

miami_v2.pdf 
newyork_v10.pdf 
rome_v1.pdf 

更新:

更改xargs的处理空格和特殊字符。