Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

how to use perl variable in system command to run on unix

by tousifp (Novice)
on Sep 03, 2013 at 16:25 UTC ( #1052139=perlquestion: print w/replies, xml ) Need Help??
tousifp has asked for the wisdom of the Perl Monks concerning the following question:

Kindly help. My following code is not working

$grep_date="$mon $arr[2]"; print "$grep_date\n"; my $files=system(q(cd /waslogs1/vfoneLog/cposapp && ls -lrt | grep -i +"$grep_date" | awk '{ print $9 }' > /home/cpos/CRM_Reports/output/fil +elist.txt));

I've assigned $mon and $arr2 to $grep_date and used it in system. The thing is I am not getting result as expected. For example, if $grep_date is "Sep 02" then the filelist.txt contains nothing Why is not grepping "Sep 02" from listing? Please resolve asap

Replies are listed 'Best First'.
Re: how to use perl variable in system command to run on unix
by toolic (Bishop) on Sep 03, 2013 at 16:36 UTC
    q prevents variable interpolation. So, $grep_date is not taking on the value 'Sep 02' inside your system call. It remains the literal string $grep_date. Try something like:
    my $cmd = 'cd /waslogs1/vfoneLog/cposapp && ls -lrt | grep -i "' . $grep_date . q(" | awk '{ print $9 }' > /home/cpos/CRM_Reports/output/filelis +t.txt); system $cmd;

    Also, system returns an exit status, not a command output. Look at qx.

      I exceuted your lines like this but no result

      my $cmd = 'cd /waslogs1/vfoneLog/cposapp && ls -lrt | grep -i "'. $gr +ep_date. q(" | awk '{ print $9 }' > /home/cpos/CRM_Reports/output/fil +elist.txt); system $cmd;

      filelist.txt is not written

Re: how to use perl variable in system command to run on unix
by betterworld (Curate) on Sep 03, 2013 at 16:58 UTC


    use Path::Class qw(dir file); use Time::localtime; my $dirpath = dir("/waslogs1/vfoneLog/cposapp"); my $outfile = file("/home/cpos/CRM_Reports/output/filelist.txt")->open +w; my @names = grep { my $st = $_->stat or die $!; localtime($st->mtime)->mon == 8 && # 8 means September localtime($st->mtime)->mday == 3 } $dirpath->children; $outfile->print($_->basename, "\n") for @names; $outfile->close or die $!;

    Ok, it's a bit longer. However you don't suffer any problems like

    • Incompatible versions of awk, ls
    • File names with spaces, or file names which have a date in them
    • Executable shell code in your $arr[2] variable
    • Flexible handling of error conditions like when one of those two path names is missing.
    • I think there is more
Re: how to use perl variable in system command to run on unix
by chromatic (Archbishop) on Sep 03, 2013 at 16:36 UTC

    $grep_date won't interpolate in the singly-quoting q() construct. When you change to a double-quoting construct, be sure to escape the dollar sign in awk's $9 argument.

    Improve your skills with Modern Perl: the free book.

      Thanks Chromatic. I changed this line as said : my $files=system(qq(cd /waslogs1/vfoneLog/cposapp && ls -lrt | grep -i "$grep_date" | awk '{ print \$9 }' > /home/cpos/CRM_Reports/timelogic/filelist.txt)); Its working now. But can you explain me what was the problem with previous line.

      And what if I use :
      my $cmd=q(cd /waslogs1/vfoneLog/cposapp && ls -lrt | grep -i "$grep_da +te" | awk '{ print $9 }' > /home/cpos/CRM_Reports/timelogic/filelist. +txt); my $files=system($cmd);

      This is still not working

        q does not expand variables, for that you need qq e.g.
        % perl -E '$x = "hello"; say q($x)' $x % perl -E '$x = "hello"; say qq($x)' hello
Re: how to use perl variable in system command to run on unix
by Laurent_R (Canon) on Sep 03, 2013 at 22:47 UTC

    I would suggest that you use Perl, rather than system commands in Perl. Especially, calling awk from Perl is a kind of disgrace, since Perl can do internally everything that awk can do, and much more, better, with finer controls and often faster (nothing against awk, which I am still using quite regularly, but much less than before I started Perl). I don't have time now to write an equivalent script in Perl, but just an example on how to get a similar result shown here as 3 simple commands under the Perl debugger:

    $ perl -de 42 Loading DB routines from version 1.33 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(-e:1): 42 DB<1> opendir $dirh, "Old_PL_programs" or die "could not open dir $! +"; DB<2> @list_files = readdir $dirh; DB<3> print " @list_files"; . .. [... many files omitted] + DB<4> foreach $file ( @list_files) {print $file, "\n" if 50 > -M "Ol +d_PL_programs/$file;"}; # prints files younger than 50 days

    Undoubtedly, piped Unix commands can be very powerful and are tempting, but you are starting Perl, you should try to do things in perl, and you will learn that most of that command piping could be done in Perl. For example, my above example under the debugger could be stripped down to one single line of code:

    DB<6> print join "\n", grep { -M $_ < 50 } glob ("Old_PL_programs/*. +*"); Old_PL_programs/ Old_PL_programs/ Old_PL_programs/

    Or, if I want to remove the path from the filename:

    DB<7> print join "\n", map {s/^.*\/(.+)/$1/r} grep -M $_<50, glob (" +Old_PL_programs/*.*");

    The last command above would have to be slightly changed on versions of Perl prior to 5.14.

    Update: the last command above could be better written with no dependancy on the Perl version as follows (not tested):

      DB<7> print map {s/^.*\/(.+)/$1/; "$_\n"} grep -M $_<50, glob ("Old_PL_programs/*.*");

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1052139]
Approved by toolic
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (6)
As of 2018-06-23 18:25 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (125 votes). Check out past polls.