sheabo has asked for the wisdom of the Perl Monks concerning the following question:

my $times = system("find /c,(\"210.55.54.33\", logfile)") ; This statement returns a find parameter format not correct error. The DOS command is find /c "210.55.54.33" c:\logs\log.log . OS is WINNT and Ative PERL. Any ideas ?
  • Comment on How do I call a DOS command with a /C variable in PERL ?

Replies are listed 'Best First'.
Re: How do I call a DOS command with a /C variable in PERL ?
by Fletch (Bishop) on Jan 27, 2002 at 10:06 UTC

    Calling out to find (which is the rough equivalent of fgrep, IMSMR) is kinda pointless. Just open the file and search for the text yourself. This is perl you know.

    sub log_has_ip { my( $logfile, $ip ) = @_; $ip = qr/$ip/; open( my $lfh, $logfile ) or die "Can't open $logfile: $!\n"; while( <$lfh> ) { return 1 if /$ip/; } return }

    Update: Just looked again and noticed it appears that you're trying to get output from system, which means you probably would want qx// or ``. That is, aside from the fact that you really don't need to call an external program to begin with.

    instead of system
Re: How do I call a DOS command with a /C variable in PERL ?
by particle (Vicar) on Jan 27, 2002 at 10:57 UTC
    i'm assuming here that you actually want the output from the find command, and not the exit code. as your code is written, it will return the exit code.

    below is some code that shows you the different ways of accomplishing your task.

    #!perl -w use strict; my $file = 'c:\autoexec.bat'; my $pattern = 'PATH'; my $seperator = '----------'; print "\n---find 1: using system\n"; my $t=system("find /c \"$pattern\" $file") ; print "->", $t, "<-\n"; print "\$t is the exit code\n"; print "\n---find 2: using `backticks`\n"; my $u=`find /c "$pattern" $file`; print "->", $u, "<-\n"; print "\$u is the output\n"; print "\n---find 3: 100% pure perl\n"; open(FILE, "< $file") or die("ERROR: failed to open file, $!"); # $count is initialized to prevent print from complaining # if no matches are found my $count=0; while( <FILE> ) { ++$count if /$pattern/; } close(FILE) or die("ERROR: failed to close file, $!"); print "->", $count, "<-\n"; print "\$count is the match count\n"; print " -or, if you really want the same output format as find-\n"; print "$seperator $file: $count\n";
    the output is:

    C:\WINDOWS\Desktop>perl test.pl ---find 1: using system ---------- c:\autoexec.bat: 6 ->0<- $t is the exit code ---find 2: using `backticks` -> ---------- c:\autoexec.bat: 6 <- $u is the output ---find 3: 100% pure perl ->6<- $count is the match count -or, if you really want the same output format as find- ---------- c:\autoexec.bat: 6
    on my windows98 box.

    ~Particle

Re: How do I call a DOS command with a /C variable in PERL ?
by trs80 (Priest) on Jan 27, 2002 at 12:15 UTC
    Fletch had a good suggestion, but the results it returns are not the same as the find command, since the find command will return a count of all occurance, which may or may not be important to the problem at hand. This code block will give you a count of all the times the string occurs in a file.
    my $file = "/path/to/file/and/filename"; open(LOG,"$file") or die; my $match_count; while(<LOG>) { my (@matches) = $_ =~ m/(127\.0\.0\.1)/g; $match_count += scalar(@matches); } print $match_count , "\n";

    Try to avoid system calls completely if it can helped to provide more portability and generally faster safer programs.
      Thanks trs80, Your code worked a treat. Thanks again... Kind Regards Sheabo
Re: How do I call a DOS command with a /C variable in PERL ?
by ellem (Hermit) on Jan 27, 2002 at 12:35 UTC
    back ticks. The fella under the tilde. It allows for system calls.
    However, you are limiting to yourself to _that_ system making your code non portable which is decidedly un Perlish
    Besides I hear that Windows is dying ;)
    --
    ellem@optonline.net
    There's more than one way to do it, just don't use my way.
Re: How do I call a DOS command with a /C variable in PERL ?
by data64 (Chaplain) on Jan 28, 2002 at 00:56 UTC
    $times = system( "find /c 210.55.54.33 c:\logs\log.log");

    if you want the output from find available to your perl script then use qw instead of system.

    I should point out that since you are in perl, you might want to consider using grep instead.

    use strict; open ( LOG, "C:\logs\log.log" ) or die "Opening file, $!"; my $count = scalar( grep( /210\.55\.54\.33/, <LOG> ) ); close LOG or die "closing file, $!";

    $count has the value you are looking for. Above code has not been tested

Re: How do I call a DOS command with a /C variable in PERL ?
by metadoktor (Hermit) on Jan 27, 2002 at 10:48 UTC
    As Fletch says, what you want to do is to quote the command like so:
    `your command here`
    But that may not work since there seems to be odd behavior in ActiveState's implementation of system() and `` calls as I noted in this node.

    metadoktor

    "The doktor is in."