如何确定文件是否被另一个文件使用/调用?

时间:2011-05-23 22:40:11

标签: perl bash scripting

我目前正处于大学二年级,因此我的编程技巧和知识并不像我喜欢的那样强大。我在暑假期间为一家网络开发公司做实习,我完全踩到了分配给我的第一项任务。这就是我在这里寻求帮助的原因。

在主文件夹中有许多子文件夹,每个子文件夹中有许多.js .cs和.php文件 - 大约1000个文件。但大约有300人没有被使用。我需要打开每个子文件夹,看看是否有任何其他文件使用/调用这些文件。如果不是,我需要将未使用文件的位置存储在文本文件中。

我做了一些研究,发现命令grep -r filename *就是这样做的,但在命令行上我无法弄清楚如何遍历文件夹并根据文件夹内的内容更改文件名。我的工作站在Windows中安装了Cygwin。

4 个答案:

答案 0 :(得分:1)

echo file,count >results.csv
for f in $(find . -name *.js -o -name *.cs -o -name *.php)
do
    echo $f,$(grep -cr $(basename $f) *) >> results.csv
done

这将为您提供这样的csv文件,其中包含每个文件的引用次数。

file,count
file1,3
file2,1
file3,0

编辑以在grepping之前删除文件路径

答案 1 :(得分:1)

这不需要双循环吗? (Big O 2 )。您必须在每个文件中搜索其中的每个文件实例。

我使用Perl代替Awk或BASH(尽管可以在BASH中使用)。

#! /usr/bin/env perl

use warnings;
use strict;
use feature qw(say);

use File::Find;     #Not crazy about File::Find, but it's a standard module
use File::Basename;

my %fileHash;
my @dirs = qw(foo bar barfu fufu barbar);   #List of the directories you're searching

#Finds the name of all the files. Include ALL files and not just .php, etc.

find(\&wanted, @dirs);

sub wanted {
    next if (-d $File::Find::name); #Skip directories
    $fileHash{$File::Find::name} = 0;       #Number of times file is referenced
}

# Outer Loop: Foreach file you have to parse

foreach my $fileName (keys %fileHash) {

    # We don't have to grep anything except those below.
    (my $suffix = $fileName) =~ s/.*\.//;
    next unless ($suffix eq ".js" or $suffix eq ".cs" or $suffix eq ".php");

    #Slurp up file in an array. That way, we can use the grep command
    open (FILE, $fileName) or die qq(Can't open "$fileName" for reading\n);
    my @lines = <FILE>;
    close FILE;

    # Now, look for each and every file you've got in that directory tree
    # in this particular file. This is an inner loop

    foreach my $fileToFind (keys %fileHash) {
        my $basename = basename($fileToFind);

        # If any lines in the file contain the file name, increment the hash.
        if (grep /$basename/, @lines) {
            $fileHash{$fileToFind} += 1;
        }   
    }   
}   


#Now just print out those files who never got incremented (i.e. never referenced)
foreach my $fileName (keys %FileHash) {
    next if ($fileHash{$fileName} != 0);
    say "File: $fileHash{$fileName}"
}   

我正在寻找一个查找文件基本名称而不是全名的快捷方式。从理论上讲,我应该从根目录中查找它的全名,以及它与文件本身的名称。但是,我现在懒得这样做。最有可能的是,您不必担心这一点。

答案 2 :(得分:0)

p,狡猾。至少如果你必须考虑'正在使用'位。

对于.cs,您可以拥有导入语句,这些语句不会轻易地让您断定文件是否正在使用中。导入可能在包级别上工作,除非我弄错了(更像是一个java人......)。

我认为JavaScript和php文件会变得更糟。

也许您应该问,为什么该报告首先是有价值的?

答案 3 :(得分:0)

这只是一个草案,你需要研究所有命令并做你自己的逻辑......

for file in $(find -type f -name \*.extension); do
    grep -Rl $file /in/path
done > /tmp/myfiles