Perl Grep 多种模式

发布于 2024-11-15 16:58:48 字数 697 浏览 6 评论 0原文

我有一个文件,可以说它被称为

                                 filename.c

我正在尝试查找该文件是否以以下方式之一使用

                          1.  include("filename.c");
                          2.   require("filename.c");
                          3.   x = new filename() ; 
                          4.   class new_class extends filename
                          5.   class new_class implements filename
                          6.   filename::function()

我想知道 perl 是否允许我一次执行所有上述搜索,或者我只需要执行其中一个一个?

而且我不太擅长正则表达式,所以我想知道如何 grep 字符串 扩展文件名 实现文件名

之间的空格给我带来了问题。提前致谢。

I have a file lets say it is called

                                 filename.c

I am trying to find if the file is being used in one of the following ways

                          1.  include("filename.c");
                          2.   require("filename.c");
                          3.   x = new filename() ; 
                          4.   class new_class extends filename
                          5.   class new_class implements filename
                          6.   filename::function()

I am wondering if perl will allow me to do all the above search at once or I just have to do them one by one?

And also I am not very good at regular expressions so I am wondering how can I grep the string
extends filename
implement filename

the space in between is giving me problems. Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

等风来 2024-11-22 16:58:48

grep 有什么问题吗?

W="filename"
find . -type f -print0 | xargs -0 grep -ilP "include(\"$W\.c\")|require(\"$W\.c\")|x\s*=\s*new\s+$W()|class\s+new_class\s+extends\s+$W|class\s+new_class\s+implements\s+$W|$W::function()"

what is wrong with grep?

W="filename"
find . -type f -print0 | xargs -0 grep -ilP "include(\"$W\.c\")|require(\"$W\.c\")|x\s*=\s*new\s+$W()|class\s+new_class\s+extends\s+$W|class\s+new_class\s+implements\s+$W|$W::function()"
耶耶耶 2024-11-22 16:58:48

使用 File::Find

我已经试图为您编译一个完整的示例。但是,你说你不太擅长正则表达式,所以尽管我已经包含了你说你需要的所有匹配项,但你可以一一删除它们,直到你明白发生了什么。

您可以将此脚本保存在一个文件中,例如 script.pl,并像这样调用它:

perl script.pl dir1 dir2 并且 dir1 和 dir2 将被深度搜索。
将对所有文件和目录调用 wanted 子函数,但我添加了一项检查,以便在当前条目 ($_) 是目录时立即返回。

注意:因为我在正则表达式中添加了 /x,所以您可以添加空格来将正则表达式分成多行,以便更容易阅读。如果您需要不区分大小写的搜索,您可能需要添加 /i

use strict;
use warnings;
use File::Find;

my $filename_to_check = 'filename'; ## or you could set it as first arg and say
                                    ## my $filename_to_check = shift @#ARGV;
my $filename_check = qr/(?:
            include\s*\(\s*"$filename_to_check\.c"\s*\)|
            require\s*\(\s*"$filename_to_check\.c"\s*\)|
            new\s+$filename_to_check\s*\(|
            class\s+\S+\s+extends\s+$filename_to_check|
            class\s+\S+\s+implements\s+$filename_to_check|
            $filename_to_check\::[\w]+\s*\(\s*\)
        )/x;

&find(\&wanted,@ARGV); ## where ARGV has all the directories you want to search

sub wanted
{
    ## don't try to open directories like files
    ## you can also return (exit wanted for current file) based on file extension.
    ##    or other arbitrary reasons.
    return if -d $_;

    eval
    {
        open F,$_ || die "Can't read $File::Find::name, $!\n";
        my $found = 0;
        while(<F>)
        {
            if($_ =~ $filename_check)
            {
                $found ++;
                print $_;
            }
        }
        if($found)
        {
            print "Found $found matches in file, $File::Find::name\n";
        }
    };
    if($@)
    {
        print STDERR $@;
    }
}

Use File::Find

I've tried to compile a complete example for you. But, you say you aren't very good at regular expressions, so though I've included all of the matches you said you need, you could eliminate them one by one till you understand what's going on.

You could save this script in a file, say script.pl, and call it like this:

perl script.pl dir1 dir2 and dir1 and dir2 will be deeply searched.
The wanted sub will be called on all files and directories, but I've added a check to return immediately if the current entry ($_) is a directory.

NOTE: Because I added /x to the regex you can add whitespace to break up the regex on multiple lines so that it's easier to read. You may want to add /i if you need case-insensitive searching.

use strict;
use warnings;
use File::Find;

my $filename_to_check = 'filename'; ## or you could set it as first arg and say
                                    ## my $filename_to_check = shift @#ARGV;
my $filename_check = qr/(?:
            include\s*\(\s*"$filename_to_check\.c"\s*\)|
            require\s*\(\s*"$filename_to_check\.c"\s*\)|
            new\s+$filename_to_check\s*\(|
            class\s+\S+\s+extends\s+$filename_to_check|
            class\s+\S+\s+implements\s+$filename_to_check|
            $filename_to_check\::[\w]+\s*\(\s*\)
        )/x;

&find(\&wanted,@ARGV); ## where ARGV has all the directories you want to search

sub wanted
{
    ## don't try to open directories like files
    ## you can also return (exit wanted for current file) based on file extension.
    ##    or other arbitrary reasons.
    return if -d $_;

    eval
    {
        open F,$_ || die "Can't read $File::Find::name, $!\n";
        my $found = 0;
        while(<F>)
        {
            if($_ =~ $filename_check)
            {
                $found ++;
                print $_;
            }
        }
        if($found)
        {
            print "Found $found matches in file, $File::Find::name\n";
        }
    };
    if($@)
    {
        print STDERR $@;
    }
}
半世蒼涼 2024-11-22 16:58:48

我认为您正在寻找 |,正则表达式“或”运算符。

/include\("filename\.c"\);|require\("filename\.c"\);|x = new filename\(\) ;|class new_class extends filename|class new_class implements filename|filename::function\(\)\*/

I think you're looking for |, the regex "or" operator.

/include\("filename\.c"\);|require\("filename\.c"\);|x = new filename\(\) ;|class new_class extends filename|class new_class implements filename|filename::function\(\)\*/
花间憩 2024-11-22 16:58:48

对于“class BLAH extends FOO”,您可能需要类似

/class\s+\S+\s+extends\s+\S+/
  • \s 匹配任何类型的空白,
  • \S 匹配任何类型的非空白,
  • + 后缀表示“一个或多个”,因此“\s+”表示“一个或多个”更多空白”。

For "class BLAH extends FOO" you might want something like

/class\s+\S+\s+extends\s+\S+/
  • \s matches any kind of whitespace,
  • \S matches any kind of non-whitespace,
  • the + suffix means "one or more of", so "\s+" means "one or more whitespace".
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文