如何通过basename比较(在shell脚本中)两个文件然后丢弃一个?

时间:2014-11-18 04:52:16

标签: macos bash perl shell

我在OS X(10.7)上使用bash shell。我有很多像这样的音频文件目录:

dir/audio.mp3
dir/audio.m4a

我想以编程方式丢弃其中一个文件,但是如何?我知道如何获得基本名称:

find . -type f -exec basename -a {} + | sort | awk -F"." '{print $1}' | uniq -d

但是,我很难说如何'标记'mp3,所以rm可以做到这一点。理想情况下,我会保留最高比特率的文件,但现在通过文件扩展名进行切换。

也许Perl是更好的工具,但我对Perl的熟练程度不足以开始解决这个问题。

2 个答案:

答案 0 :(得分:3)

在Perl中,你想要的是File::Find模块。

#!/usr/bin/perl

use strict;
use warnings;

use File::Find;

my $search_path = "dir/";

my %exists;

sub find_dupes {
    my $filename = $_;
    $filename =~ s/\.\w+$//;    #remove extension)
    if ( $exists{$filename} ) {
        print $File::Find::name, " may be a duplicate of ",
            $exists{$filename}, "($filename)\n";

        ##maybe delete the duplicate via unlink();
    }
    else {
        $exists{$filename} = $File::Find::name;
    }
}

find( \&find_dupes, $search_path );

注意:实际上没有删除。那是留给你的。您可以使用File::Find进行更巧妙的比较,例如修改时间,文件大小。您甚至可以使用MP3::Info等模块自动提取MP3元数据。我没用过那个,所以YMMV。

答案 1 :(得分:1)

您可以使用basename命令获取文件的基本名称(看起来您正在从find执行此步骤...):

$ file="/foo/bar/baz.ext"
$ echo $file
/foo/bar/baz.ext

$ name="$(basename "$file")"
$ echo $name
baz.ext

然后要删除扩展程序,请使用%.* 参数扩展删除最后一个点及其后的所有内容:

$ base="${name%.*}"
$ echo $base
baz

man bash,搜索“参数扩展”以获取更多信息。这也适用于ksh / zsh。