marco.shaw has asked for the wisdom of the Perl Monks concerning the following question:

**Perl novice**

Have googled around a bit. There's some solutions out there, but I want to understand what I'm trying to run.

What might I be missing below, because it doesn't seem to work on UNIX?

$ cat test1.pl #!/usr/bin/perl $string = 'test'; $inputs = 'test.txt'; open(TABLE, $inputs) or die "can't open $inputs.\n"; while ( $line = <TABLE> ) { if ( $_ =~ $string ) { print $_; } } close(IN); $ cat test.txt test tst $

In the end, I'm looking to match a string, but then have it return the 2nd portion. The file I'm searching will be of the form:

something:somethingelse

I want to search for "something", but have "somethingelse" returned (after the colon).

Edit: g0n - code tags & formatting

Replies are listed 'Best First'.
Re: Searching through a file
by ikegami (Patriarch) on Sep 05, 2007 at 18:25 UTC

    Four problems. (Aside from not previewing your node. Use <c>...</c> around code in your nodes.)

    • You call your file handle TABLE, table and IN. The name is case-sensitive, and using the wrong name obviously won't work. Furthermore, you're better off using lexical file handles:

      open(my $fh, '<', $inputs) or die ... while (<$fh>) { ... } close($fh); # Optional.
    • Similarly, you read each line into $line, yet you use $_ further on.

    • Third, keep in mind that the lines returned by the <HANDLE> operator include a trailing newline. Use chomp($line); as the first line of the while loop if you wish to remove this newline.

    • Finally, you treat $string as if it's a regexp while it's probably just text. (Added for clarification: If $string contains text as opposed to a regexp, you can convert the text to a regexp using \Q...\E or quotemeta. )

      if ($line =~ /\Q$string\E/) { ... }

      If you want to check for equality:

      if ($line eq $string) { ... }
      if ($line =~ /\Q$string\E/) { ... }

      This is a good idea. I didn't make the leap to quoting the string when building the regex, but that's probably what the OP wants.

Re: Searching through a file
by mr_mischief (Monsignor) on Sep 05, 2007 at 18:13 UTC
    Welcome to Perlmonks.

    Is this what the actual code looks like?

    #!/usr/bin/perl $string = 'test'; $inputs = 'test.txt'; open(TABLE, $inputs) or die "can't open $inputs.\n"; while ( $line = <IN> ) { if ( $_ =~ $string ) { print $_; } } close(IN);
    ( See Writeup Formatting Tips for info on getting your code into the node. )

    If that's the case, then I see at least these problems at a glance:

    • you're not reading the file you are opening. You're certainly not closing the one you're opening. open and close will tell you about what those items you're passing to open() and close() do.
    • You're also assigning the readline (<filename>) operator's results to $line, then working on $_ which is the default variable which would have otherwise taken that value. perlvar can help you figure that out.
    • You then test a scalar variable against a scalar variable without anything other than the binding operator. You need a regular expression match. perlre and Regexp Quote Like Operators operator, regexp should help with that.

    You might try the below code (untested):

    #!/usr/bin/perl use strict; use warnings; my $string = 'test'; my $inputs = 'test.txt'; # see perlfunc open( my $in, '<', $inputs) or die "can't open $inputs.\n"; while ( <$in> ) { # see perlsyn, perlop if ( $_ =~ m/^$string(.*)/ ) { # see perlre print $1; # see perlvar, perlre } } close( $in ); # see perlfunc
    If, on the other hand, you want to just split on the first space instead of actually matching:
    #!/usr/bin/perl use strict; use warnings; while ( <> ) { # takes filenames on the command line or STDIN if none print ( ( split )[1] ); }
    perlvar, perlop, perlre, perlfunc are recommended reading. Also, if you're new to programming, consider Learning Perl. If you're a programmer new to Perl, consider Programming Perl.

    BTW, Perl is a wonderful tool, but you might also want to 'man 1 cut' if you're using a Unixy OS.

    Update: The code was missing a couple of $ sigils. Thanks to ikegami for pointing it out to me.

Re: Searching through a file
by dwm042 (Priest) on Sep 05, 2007 at 19:30 UTC
    The only thing I'd add to what mr_mischief and ikegami have said, is that it can be useful to use __DATA__ to set up some test data before your loop and then test to see that your loop does what you want it to, as so:

    #!/usr/bin/perl use warnings; use strict; # # Using __DATA__ to test a loop. # my $string = 'test'; my $inputs = 'test.txt'; # open(my $table, "<", $inputs) or die "can't open $inputs.\n"; # while (<$table>) { while (<DATA>) { print if ( m/\Q$string\E/o ); } # close($table); __DATA__ test tst foo bar test This is a test This is something else.
    The output is:

    C:\Code>perl match.pl test foo bar test This is a test
Re: Searching through a file
by FunkyMonk (Bishop) on Sep 05, 2007 at 21:31 UTC
    You may have noticed that a couple of Monks included
    use strict; use warnings;

    near the start of the programs they posted. Those two statements are the most important Perl you'll ever learn. Put them in every program you write. They will save you many, many hours of heartache.

Re: Searching through a file
by toolic (Bishop) on Sep 05, 2007 at 17:52 UTC
    Your question will be difficult to answer unless you:

    Use code tags. Refer to Writeup Formatting Tips.

    Show your exact input data.

    Show your desired output data.

Re: Searching through a file
by klekker (Pilgrim) on Sep 06, 2007 at 10:39 UTC
    What might I be missing below, because it doesn't seem to work on UNIX +?

    ... PrivoxyWindowOpen(TABLE, $inputs) or die "can't open $inputs.\n"; ...
    Correct me if I'm wrong, but: I think you should use open if you want to open a file on a _UNIX_ System.

    k