【问题标题】:Read content from file and find full file-name on disk从文件中读取内容并在磁盘上找到完整的文件名
【发布时间】:2009-06-08 05:17:20
【问题描述】:

我的问题是我有一堆没有附加版本的文件名(版本每次都在变化)。文件名按特定顺序位于文件中,我需要从文件夹中获取最新版本,然后按顺序安装。逻辑是:

  1. 扫描包含内容的文件
    • 从文件中读取一行
    • 使用它作为密钥,访问文件夹并匹配它
    • 如果找到,将完整的文件名写入附加一些字符的文件中
    • 如果没有找到,跳过并循环到第 1 行,直到文件中的所有行都完成

最好使用哪种语言:shell 脚本或 Perl 来完成这样的任务?如果有人可以以代码的形式提供一些提示:-)

【问题讨论】:

    标签: perl shell


    【解决方案1】:

    我会读入您所有的部分文件名,然后遍历将完整文件名与部分文件名匹配的文件夹。确切的实现将取决于一些细节。 完整文件名是否需要以与部分文件名相同的顺序出现?你能从完整的文件名中导出部分文件名吗?

    更新:所以,类似(假设 $infile、$outfile 和 $indir 已打开文件和目录句柄,以及一个翻译例程 partial_filename_from_full 为目录或非相关文件返回 undef):

    chomp( my @partial_filenames = readline( $infile ) );
    
    while ( my $filename = readdir( $indir ) ) {
        my $partial_filename = partial_filename_from_full( $filename );
        if ( defined $partial_filename ) {
            $full_filename{ $partial_filename } = $filename;
        }
    }
    
    for my $partial_filename ( @partial_filenames ) {
        if ( exists $full_filename{ $partial_filename } ) {
            print $outfile $full_filename{ $partial_filename }, "\n";
        } else {
            # error? just skip it? you decide
        }
    }
    

    如果每个部分文件名有多个完整文件名,而不是分配:

            $full_filename{ $partial_filename } = $filename;
    

    您将确定 $filename 是否比之前遇到的“匹配”更好 一个。

    【讨论】:

    • 是的,完整的文件名需要以与部分文件名相同的顺序出现。是的,部分文件名(由 Jonathan 给出)是没有附加文件版本的初始名称,因此完整的文件名可以从部分文件名中派生出来。
    【解决方案2】:

    你的问题不是很清楚,但我猜你有一个包含文件名的目录,例如:

    • 文件A01
    • 文件A02
    • 文件B03
    • 文件B05
    • 文件B12
    • 文件C02
    • 文件D09
    • 文件E22

    您扫描的“带有内容”的文件包含一个名称列表,例如:

    • 文件A
    • 文件B
    • 文件E

    而你想让代码在对应文件名的最高版本号的目录中找到入口:

    • 文件A02
    • 文件B12
    • 文件E22

    您必须准确决定如何比较版本 - 我使用的是 2 位版本号,但您没有说明您的限制条件。

    我可能会为此使用 Perl。首先,我将整个“带有内容的文件”读入内存,然后创建一个怪物正则表达式来识别文件名——可能包括版本号检测。我会使用opendirreaddir(和closedir)来处理目录。对于每一行,我会将其与正则表达式进行匹配,并捕获该名称是否是任何所查找文件的最新版本。如果是这样,我会在哈希中捕获文件名,由无版本文件名索引(因此,如果首先读取 fileA01,那么我将拥有$filelist{fileA} = "fileA01";,当然哈希键和完整文件名都是在变量中。

    在 shell 中做会更难。使用 Bash 最强大的功能,这可能是可行的;我仍然会使用 Perl(或 Python,或任何脚本语言)。

    【讨论】:

    • 是的,您的上述假设是正确的。我会试试你给的。谢谢:-)
    【解决方案3】:

    我会使用 awk。

    awk -f myawk.awk

    myawk.awk

    BEGIN{
    }
    {
        myfilename = $0;
        retval = getline otherfile < myfilename;
        if (retval == -1) # check the correct syntax
        {
            # file does not exist. do the necessary error handling
    
        }
        else
        {
            # File exists. so do what you want.
            # perhaps you might want to write to a new file with the modified filename
        }
    }
    END{
    }
    

    【讨论】:

    • 一个空的 'BEGIN' 有点奇怪 - 为什么要包含它?您的代码似乎没有处理部分名称与全名问题。
    • 真的。拥有骨架BEGIN-END对我来说更成为一种习惯。在上面的代码中,我通过 awk 暗示了一个可能的解决方案,并没有尝试提供运行代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 2018-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多