如何在Perl中搜索特定列?

时间:2022-03-23 08:01:30

I have a text file which contains some data. I am trying to search for EA in ID column only and prints the whole row. But the code recognize all EA and prints all rows. What code I should add to satisfy the condition? Thanks Again:-)!

我有一个包含一些数据的文本文件。我试图仅在ID列中搜索EA并打印整行。但代码识别所有EA并打印所有行。我应该添加什么代码来满足条件?再次感谢:-)!

DATA:
Name Age ID
---------------------
KRISTE,22,EA2008
JEAN,21,ES4567
JAK,45,EA2008

The code prints:
KRISTE,22,EA2008
JEAN,21,ES4567
JAK,45,EA2008

数据:姓名年龄ID --------------------- KRISTE,22,EA2008 JEAN,21,ES4567 JAK,45,EA2008代码打印:KRISTE,22,EA2008 JEAN,21,ES4567 JAK,45,EA2008

Desired output:
KRIS,22,EA2008
Kane,45,EA2008,

期望的输出:KRIS,22,EA2008 Kane,45,EA2008,

file='save.txt';
open(F,$file)||die("Could not open $file");
while ($line=<F>){
if ($line=~ m/$EA/i) {
my @cells=($f1,$f2,$f3)= split ',',$line;
print "<TD>f1</TD>";
print "<TD>f2</TD>";
print "<TD>f3</TD>";
}

6 个解决方案

#1


8  

A combination of brian's and Jeremy's code fixes all the problems:

brian和Jeremy的代码组合修复了所有问题:

use strict;
use warnings;

my $file = 'save.txt';
open my $fh, "<", $file or die "Could not open $file: $!";

while ($line = <$fh>)
{
    my($f1, $f2, $f3) = split ',', $line;
    if ($f3 =~ m/EA/i)
    {
        print "<TD>$f1</TD>";
        print "<TD>$f2</TD>";
        print "<TD>$f3</TD>";
    }
}

Brian had generalized the match pattern with use CGI; and my $EA = param('keyword'); but I undid that as I didn't see it as applicable to the question.

Brian使用CGI推广了匹配模式;和我的$ EA = param('keyword');但我解除了这一点,因为我没有看到它适用于这个问题。

#2


6  

You should post the actual sample program you are using to illustrate the problem. Here's your cleansed program:

您应该发布用于说明问题的实际示例程序。这是你的清洁程序:

use strict;
use warnings;

use CGI;

my $EA = param('keyword');

my $file = 'save.txt';
open my $fh, "<", $file or die "Could not open $file: $!";

while( $line=<$fh> ) {
   if( $line=~ m/$EA/i ) {
       my( $f1, $f2, $f3 ) = split ',', $line;
       print "<TD>$f1</TD>";
       print "<TD>$f2</TD>";
       print "<TD>$f3</TD>";
       }
   }

Here's a few things that can help you.

这里有一些可以帮到你的东西。

  • Your variables need their sigils. They don't do anything without them.
  • 你的变量需要他们的印记。没有他们,他们什么都不做。

  • When you try to open a file and want to report an error, include the $! variable so you see what the error is.
  • 当您尝试打开文件并想要报告错误时,请包含$!变量,所以你看到错误是什么。

  • You can split directly to scalar variables. It's just a list assignment. You don't need the extra @cell variable.
  • 您可以直接拆分为标量变量。这只是一个列表分配。您不需要额外的@cell变量。

  • Give your statements some room to breathe by using some whitespace. It's free, after all.
  • 使用一些空格为你的陈述提供一些呼吸空间。毕竟,它是免费的。

#3


4  

You almost had it, I think this should work:

你几乎拥有它,我认为这应该工作:

file='save.txt';
open(F,$file)||die("Could not open $file");

while ($line=<F>){
  my @cells=($f1,$f2,$f3)= split ',',$line;
  if ($f3=~ m/$EA/i) {
    print "<TD>f1</TD>";
    print "<TD>f2</TD>";
    print "<TD>f3</TD>";
  }
}

This splits the line into columns first, and then does the regex only on the third column.

这会先将行拆分为列,然后仅在第三列上执行正则表达式。

BTW your code may have other problems (for example those print statements don't look like they print the values of your variables) but I don't know perl very well so I only answered your main question...

顺便说一句你的代码可能有其他问题(例如那些打印语句看起来不像打印变量的值)但我不太了解perl所以我只回答了你的主要问题......

#4


2  

Rather than trying to do the CSV parsing yourself, use the excellent and efficient Text::CSV_XS. This will handle escapes and quoting.

不要尝试自己进行CSV解析,而是使用优秀且高效的Text :: CSV_XS。这将处理转义和引用。

#!/usr/bin/perl -w

use Text::CSV_XS;

my $csv = Text::CSV_XS->new();

# Skip to the data.
while(<DATA>) {
    last if /^-{10,}$/;
}

while( my $row = $csv->getline(*DATA) ) {
    print "@$row\n" if $row->[2] =~ /EA/;
}


__DATA__
Name Age ID
---------------------
KRISTE,22,EA2008
J**EA**N,21,ES4567
JAK,45,EA2008

#5


1  

Alternately, you could alter your regex to just match the third item in the list:

或者,您可以更改正则表达式以匹配列表中的第三个项目:

/[^,]*,[^,]*,.*EA/

#6


0  

Your regex is incorrect for what you are trying to do. Ben's solution works, although there should also be a ^ at the start, which ensures that the regex will start matching from the start of the string:

您的正则表达式对于您要执行的操作不正确。 Ben的解决方案有效,虽然在开始时也应该有一个^,这可以确保正则表达式从字符串的开头开始匹配:

/^.?,.?,.*EA/

Also, your code is kinda noisy, from a perl point of view. If you want to make your code easier to read, you can do this (I'm using Ben's regex):

此外,从perl的角度来看,您的代码有点吵。如果你想让你的代码更容易阅读,你可以这样做(我正在使用Ben的正则表达式):

$f = 'save.txt';

$ f ='save.txt';

open( F, $file );

打开(F,$ file);

@matches = grep { /^.?,.?,.*EA/ } <F>;

@matches = grep {/^.?,.?,.*EA/} ;

Now @matches will hold all your matched records, you can do what you want with them.

现在@matches将保存所有匹配的记录,您可以随意使用它们。

#1


8  

A combination of brian's and Jeremy's code fixes all the problems:

brian和Jeremy的代码组合修复了所有问题:

use strict;
use warnings;

my $file = 'save.txt';
open my $fh, "<", $file or die "Could not open $file: $!";

while ($line = <$fh>)
{
    my($f1, $f2, $f3) = split ',', $line;
    if ($f3 =~ m/EA/i)
    {
        print "<TD>$f1</TD>";
        print "<TD>$f2</TD>";
        print "<TD>$f3</TD>";
    }
}

Brian had generalized the match pattern with use CGI; and my $EA = param('keyword'); but I undid that as I didn't see it as applicable to the question.

Brian使用CGI推广了匹配模式;和我的$ EA = param('keyword');但我解除了这一点,因为我没有看到它适用于这个问题。

#2


6  

You should post the actual sample program you are using to illustrate the problem. Here's your cleansed program:

您应该发布用于说明问题的实际示例程序。这是你的清洁程序:

use strict;
use warnings;

use CGI;

my $EA = param('keyword');

my $file = 'save.txt';
open my $fh, "<", $file or die "Could not open $file: $!";

while( $line=<$fh> ) {
   if( $line=~ m/$EA/i ) {
       my( $f1, $f2, $f3 ) = split ',', $line;
       print "<TD>$f1</TD>";
       print "<TD>$f2</TD>";
       print "<TD>$f3</TD>";
       }
   }

Here's a few things that can help you.

这里有一些可以帮到你的东西。

  • Your variables need their sigils. They don't do anything without them.
  • 你的变量需要他们的印记。没有他们,他们什么都不做。

  • When you try to open a file and want to report an error, include the $! variable so you see what the error is.
  • 当您尝试打开文件并想要报告错误时,请包含$!变量,所以你看到错误是什么。

  • You can split directly to scalar variables. It's just a list assignment. You don't need the extra @cell variable.
  • 您可以直接拆分为标量变量。这只是一个列表分配。您不需要额外的@cell变量。

  • Give your statements some room to breathe by using some whitespace. It's free, after all.
  • 使用一些空格为你的陈述提供一些呼吸空间。毕竟,它是免费的。

#3


4  

You almost had it, I think this should work:

你几乎拥有它,我认为这应该工作:

file='save.txt';
open(F,$file)||die("Could not open $file");

while ($line=<F>){
  my @cells=($f1,$f2,$f3)= split ',',$line;
  if ($f3=~ m/$EA/i) {
    print "<TD>f1</TD>";
    print "<TD>f2</TD>";
    print "<TD>f3</TD>";
  }
}

This splits the line into columns first, and then does the regex only on the third column.

这会先将行拆分为列,然后仅在第三列上执行正则表达式。

BTW your code may have other problems (for example those print statements don't look like they print the values of your variables) but I don't know perl very well so I only answered your main question...

顺便说一句你的代码可能有其他问题(例如那些打印语句看起来不像打印变量的值)但我不太了解perl所以我只回答了你的主要问题......

#4


2  

Rather than trying to do the CSV parsing yourself, use the excellent and efficient Text::CSV_XS. This will handle escapes and quoting.

不要尝试自己进行CSV解析,而是使用优秀且高效的Text :: CSV_XS。这将处理转义和引用。

#!/usr/bin/perl -w

use Text::CSV_XS;

my $csv = Text::CSV_XS->new();

# Skip to the data.
while(<DATA>) {
    last if /^-{10,}$/;
}

while( my $row = $csv->getline(*DATA) ) {
    print "@$row\n" if $row->[2] =~ /EA/;
}


__DATA__
Name Age ID
---------------------
KRISTE,22,EA2008
J**EA**N,21,ES4567
JAK,45,EA2008

#5


1  

Alternately, you could alter your regex to just match the third item in the list:

或者,您可以更改正则表达式以匹配列表中的第三个项目:

/[^,]*,[^,]*,.*EA/

#6


0  

Your regex is incorrect for what you are trying to do. Ben's solution works, although there should also be a ^ at the start, which ensures that the regex will start matching from the start of the string:

您的正则表达式对于您要执行的操作不正确。 Ben的解决方案有效,虽然在开始时也应该有一个^,这可以确保正则表达式从字符串的开头开始匹配:

/^.?,.?,.*EA/

Also, your code is kinda noisy, from a perl point of view. If you want to make your code easier to read, you can do this (I'm using Ben's regex):

此外,从perl的角度来看,您的代码有点吵。如果你想让你的代码更容易阅读,你可以这样做(我正在使用Ben的正则表达式):

$f = 'save.txt';

$ f ='save.txt';

open( F, $file );

打开(F,$ file);

@matches = grep { /^.?,.?,.*EA/ } <F>;

@matches = grep {/^.?,.?,.*EA/} ;

Now @matches will hold all your matched records, you can do what you want with them.

现在@matches将保存所有匹配的记录,您可以随意使用它们。