【问题标题】:how to find the first occurrence of a string in all the files in a folder in perl如何在perl的文件夹中的所有文件中查找第一次出现的字符串
【发布时间】:2013-02-07 22:34:05
【问题描述】:

我正在尝试在文件夹中的每个 txt 文件中查找字符串“victory”第一次出现的行。对于文件中的每个第一个“胜利”,我想将该行中的数字保存到 @num 并将文件名保存到 @filename

示例:对于以以下行开头的文件 a.txt:“lalala 胜利 123456”-> $num[$i]=123456 和 $filename[$i]="a.txt"

ARGV 保存所有文件名。我的问题是我试图逐行进行,但我不知道自己做错了什么。 还有一件事-我怎样才能在最后一个文件中获得最后一次出现的“胜利”?

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

my $dir = "D:/New folder";   
find(sub { if (-f && /\.txt$/) { push @ARGV, $File::Find::name } }, $dir);   $^I = ".bak"; 

my $argvv;
my $counter=0;
my $prev_arg=0;
my $line = 0;

my @filename=0;
my @num=0;
my $i = 0;

foreach $argvv (@ARGV)
{
    #open $line, $argvv or die "Could not open file: $!";
    my $line = IN 
    while (<$line>)
    {
        if (/victory/)
        {
            $line = s/[^0-9]//g;    
            $first_bit[$i] = $line;
            $filename[$i]=$argvv;
            $i++;
            last;
        }

    }
    close $line;
}


for ($i=0; $i<3; $i++)
{
    print $filename[$i]."  ".$num[$i]."\n";
}

非常感谢! :)

【问题讨论】:

  • last-occurrencefindfirst 是标签吗?真的吗?

标签: perl


【解决方案1】:

您的示例脚本有一些小问题。以下示例应该以相当干净的方式执行您想要的操作:

#!/usr/bin/perl 
use strict;
use warnings;
use File::Find;

# Find the files we're interested in parsing
my @files = ();
my $dir = "D:/New folder";
find(sub { if (-f && /\.txt$/) { push @files, $File::Find::name } }, $dir);

# We'll store our results in a hash, rather than in 2 arrays as you did
my %foundItems = ();

foreach my $file (@files)
{
    # Using a lexical file handle is the recommended way to open files
    open my $in, '<', $file or die "Could not open $file: $!";
    while (<$in>)
    {
        # Uncomment the next two lines to see what's being parsed
        # chomp; # Not required, but helpful for the debug print below
        # print "$_\n"; # Print out the line being parsed; for debugging

        # Capture the number if we find the word 'victory'
        # This assumes the number is immediately after the word; if that
        # is not the case, it's up to you to modify the logic here
        if (m/victory\s+(\d+)/)
        {
            $foundItems{$file} = $1; # Store the item
            last;
        }
    }
    close $in;
}

foreach my $file (sort keys %foundItems)
{
    print "$file=> $foundItems{$file}\n";
}

【讨论】:

  • 谢谢!我使用了您的代码,由于某种原因,它只读取具有偶数行号的行:第二行,第四行,第六行......我真的不明白怎么可能。我真的很感激一些帮助,因为我是一个完全的菜鸟。谢谢!
  • while 循环读取它处理的每个文件中的每一行,但只存储victory &lt;some_number&gt; 的第一个实例。会不会是你的命中恰好在偶数行上?您可以在循环中添加一个打印语句 (print "$_\n";) 以准确查看正在解析的内容。在该循环的顶部添加chomp; 也可能会有所帮助。我将修改我的示例以包含这些内容。
  • 有效!谢谢!我的问题是在内部循环中我写了 $line = 所以我每隔一行就得到了。现在对我来说很有意义。这是一个非常愚蠢的错误。非常感谢您的帮助!
【解决方案2】:

下面在所有文件(文件*.txt)中搜索字符串 abc 并仅打印第一行。

perl -lne 'BEGIN{$flag=1}if(/abc/ && $flag){print $_;$flag=0}if(eof){$flag=1}' file*.txt

测试:

> cat temp
abc 11
22
13
,,
abc 22
bb
cc
,,
ww
kk
ll
,,

> cat temp2
abc t goes into 1000
fileA1, act that abc specific place

> perl -lne 'BEGIN{$flag=1}if(/abc/ && $flag){print $_;$flag=0}if(eof){$flag=1}' temp temp2
abc 11
abc t goes into 1000
> 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    • 2017-04-16
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    • 2016-08-01
    相关资源
    最近更新 更多