0

Alright, so the question heading might be a bit confusing. I have replicated my actual problem in below code:

I am creating files with two different IP addresses as a prefix and then I want to list the files only with a particular ip address prefix:

I am creating files with "10.10.10.10" and "11.11.11.11" as prefix and then I want to list files only with the "10.10.10.10" prefix.

Here is my code:

#!/usr/bin/perl -w
use strict;

my $ipaddr1 = '10.10.10.10';
for ( my $counter = 1; $counter < 10; $counter++)
{
    my $filename = $ipaddr1."_".$counter.".txt";
    open (my $fh, ">", $filename) or die "$! \n";
}

my $ipaddr2 = '11.11.11.11';
for ( my $counter = 1; $counter < 10; $counter++)
{
    my $filename = $ipaddr2."_".$counter.".txt";
    open (my $fh, ">", $filename) or die "$! \n";
}
print "Done with creating hte files. \n";

print "Lets print the files with only 10.10.10.10 prefix \n";

for my $var ( `ls -1 $ipaddr1_*` )  ### <<< this is the probelm
{
    print $var;
}

Output:

Global symbol "$ipaddr1_" requires explicit package name at test.pl line 21.
Execution of test.pl aborted due to compilation errors.

So, I fully understand the error that it is not able to interpret the perl variable while executing a bash command.

Question:

how to achieve this? I do not want to pass explicit IP address to the ls -1 command but instead want to pass the variable which holds the respective IP address.

Thanks.

1
  • I suggest using another approach, File::Glob. Explicitly or via the angle-bracket operator, <> Commented Mar 7, 2013 at 10:34

3 Answers 3

3

The problem is that Perl interprets the underscore _ as part of the variable name. The most straightforward solution is to add disambiguating brackets so that this won't happen:

`ls -1 ${ipaddr1}_*`
Sign up to request clarification or add additional context in comments.

Comments

2

The ${ipaddr1}_ syntax given by Ilmari Karonen is the correct solution. There are a few other things that might be improved:

  1. Don't start a new process for something Perl can already do:

    for my file (glob "${ipaddr1}_*") {
      print "$file\n";
    }
    

    This is also more portable :)

  2. Be aware that open my $fh, ">", $filename will clobber the file. If you only want to create non-existing files but don't want to clobber the content, use the >> append mode instead.

  3. Make your life easy and your code short! Use loops and ranges:

    for my $ipaddr ("10.10.10.10", "11.11.11.11") {
      for my $counter (1 .. 9) {
        my $filename = sprintf "%s_%d.txt", $ipaddr, $counter;
        open my $fh, ">", $filename or die "Can't open $filename: $!";
      }
    }
    

Comments

1

Solved:

my $cmd = "ls -1 ". $ipaddr1."_*.txt";
for my $var ( `$cmd` )
{
    print $var;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.