如何在Perl中搜索特定列?

时间:2008-11-04 05:28:52

标签: perl search csv

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

数据:
姓名年龄ID
---------------------
KRISTE,22,的 EA 2008
Ĵ的 EA N,21,ES4567
JAK,45,的 EA 2008

代码打印:
KRISTE,22,的 EA 2008
Ĵ的 EA N,21,ES4567
JAK,45,的 EA 2008

期望的输出:
KRIS,22,的 EA 2008
凯恩,45,的 EA 2008,

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 个答案:

答案 0 :(得分:8)

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已将匹配模式与use CGI;my $EA = param('keyword');进行了概括,但我解除了这一点,因为我认为它不适用于该问题。

答案 1 :(得分:6)

您应该发布您正在使用的实际示例程序来说明问题。这是你清理过的程序:

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>";
       }
   }

这里有一些可以帮助你的事情。

  • 你的变量需要他们的印记。没有它们,他们什么都不做。
  • 当您尝试打开文件并想要报告错误时,请包含$!变量,以便您看到错误是什么。
  • 您可以直接拆分为标量变量。这只是一个列表分配。您不需要额外的@cell变量。
  • 使用一些空格为你的陈述提供一些呼吸空间。毕竟,它是免费的。

答案 2 :(得分:4)

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

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>";
  }
}

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

BTW您的代码可能有其他问题(例如那些打印语句看起来不像打印变量的值)但我不太了解perl因此我只回答了您的主要问题...

答案 3 :(得分:2)

不要尝试自己进行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

答案 4 :(得分:1)

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

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

答案 5 :(得分:0)

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

/ ^。?,。?,* EA /

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

$f = 'save.txt';

open( F, $file );

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

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