2014-03-03 162 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的處理空格和特殊字符。