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

HI All Actually i need to replace a string with mutiple values that is stored in some external file. can i anybody help me on this for example : i have a file1 which contain text "My name is %s" I have an second file which contain mutiple values for %s replacement i.e file2 have John, peter, jessus etc Hence i need a output file that conatins output like My name is John My name is Peter My name is jessus
  • Comment on Need to replace string from external file

Replies are listed 'Best First'.
Re: Need to replace string from external file
by hippo (Archbishop) on Nov 06, 2017 at 11:53 UTC
    i have a file1 which contain text "My name is %s" I have an second file which contain mutiple values for %s replacement i.e file2 have John, peter, jessus etc Hence i need a output file that conatins output like My name is John My name is Peter My name is jessus

    Sounds like a job for printf to me:

    #!/usr/bin/env perl use strict; use warnings; my $text = "My name is %s\n"; my @args = qw/John peter jessus/; printf $text, $_ for @args;

    File input left as an exercise.

      bro hippo for your info Replacement string are in some external file :(
        To make you more clear my first file contain line like my name is % s My local machine ip is %d My second file contains value for %s i.e john,peter,mickey My third file contains value for %d i.e 10.0.1.2, 10.2.3.4 My output should be My name is John My name is Peter My name is mickey My local machine ip is 10.0.1.2 My local machine ip is 10.2.3.4 can you please help me on getting this output ...
Re: Need to replace string from external file
by Marshall (Canon) on Nov 06, 2017 at 19:51 UTC
    I was reading this thread and I didn't see any definition of the input files until Re^4: Need to replace string from external file! In the future, please start with a very clear example of your code and the input files and the desired output.

    It is possible to make a single Perl program file that contains multiple input files for reading. I show an example below. In your case, there are 3 input files and the output goes to STDOUT. Anybody can download my single .pl file and run it and see what it does.

    You seem to be having trouble dealing with files in general. How to open a file handle, etc. The Monks have given you some great pointers on that. This is a basic thing that you need to know how to do in any programming language.

    I work with beginners in a number of programming languages at a local college. The first and most important file skill (besides how to open and close files) is to process input files one line at a time. When you create an array of the entire file in memory (slurp, etc) and then process that array, you are actually reading each data line twice and consuming memory in the process. This is usually not necessary or desired.

    Your desired code does seem a bit contrived to me. Is this a homework assignment? I would not have written an assignment like this. Having 2 files where line 3 of one matches up with line 3 of the other is pretty rare. That is because this is a very error prone format - there is a lot that can go wrong! But yes, these things do exist.

    Below I check for "defined" when reading a line from the inline file. That is because EOF (End of File) for an inline file is detected a bit differently than when reading an actual file. This extra (is defined?) step works fine with real files, but isn't necessary.

    #!/usr/bin/perl use strict; use warnings; use Inline::Files; # allows files to be included in source code my $template = <TEMPLATE>; # reads first line # $template has a trailing \n my $name; while (defined ($name = <NAME>) and $name =~ /\S+/) # process until bl +ank line { chomp $name; my $ip; defined ($ip = <IP>) and $ip =~ /\S+/ or die "Mis-matched number o +f lines"; chomp $ip; printf ($template,$name,$ip); # note uses the \n within template +line } =prints: my name is john. My local machine ip is 10.0.1.2. my name is peter. My local machine ip is 10.2.3.4. my name is mickey. My local machine ip is 10.3.4.5. =cut __TEMPLATE__ my name is %s. My local machine ip is %s. __NAME__ john peter mickey __IP__ 10.0.1.2 10.2.3.4 10.3.4.5
    Update:
    This inline file stuff can be a good idea.
    I wrote some code last week with 4 inline files, 2 input files and 2 output files. This code is now in production - this has real uses, not just theory. I include a file into the source code when I expect that the person who modifies this file later will need to understand the actual source code. This "file" is in the source code because a "programmer" is needed to modify it. That is a different thing than a configuration file which is intended to be modified by average users of the S/W.
Re: Need to replace string from external file
by Corion (Patriarch) on Nov 06, 2017 at 11:31 UTC

    Since the task itself isn't that complex, can you show us what code you have already written?

    Please also show a short example of input data, the expected output and the output you get instead.

    This way, we can give you good advice that actually adresses the code you have.

      HI Corion Please find my code as follow
      use strict; use warnings; use Path::Tiny qw(path); my $filenme='d:\SampleCiscoIOSEvent.txt'; my $file=path($filenme); my $data= $file->slurp_utf8; use File::Slurp; my $filename='e:\filename.txt'; my @arr = read_file($filename); my @output= map{ $data=~s/C_USERNAME/$_/rg} @arr; print @output;

      HI corion

      I have written this code

      use strict; use warnings; use Path::Tiny qw(path); my $filenme='d:\SampleCiscoIOSEvent.txt'; my $file=path($filenme); my $data= $file->slurp_utf8; use File::Slurp; my $filename='e:\filename.txt'; my @arr = read_file($filename); my @output= map{ $data=~s/C_USERNAME/$_/rg} @arr; print @output;

      the problem is it is working fine for one variable But if i have more then 1 variable my output is very confusing Please help me

      My code for changing more then one variable is as follow

      use strict; use warnings; use Path::Tiny qw(path); my $filenme='d:\SampleCicoIOSEvent.txt'; my $file=path($filenme); my $data= $file->slurp_utf8; use File::Slurp; my $filename='e:\filename.txt'; my $IPfilename='e:\IPfilename.txt'; my @arr = read_file($filename); my @arr1 = read_file($IPfilename); my @output= map{ $data=~s/C_USERNAME/$_/rg} @arr; my @output1= map{ $data=~s/IP/$_/rg} @arr1; print @output; print @output1;
        my @output= map{ $data=~s/C_USERNAME/$_/rg} @arr; my @output1= map{ $data=~s/IP/$_/rg} @arr1;

        This is almost correct, but note that you are storing the first transformation, using C_USERNAME in @output, and then the second transformation, using IP in @output1. Most likely, you will want to transform everything, after having replaced all C_USERNAME and all IP.

        Instead of reusing $data in the second output, you will likely want to use the elements in @output.

        my @usernames = map { $data =~ s/C_USERNAME/$_/rg } @arr; my @user_and_ip; for my $user_string (@usernames) { push @user_and_ip, map { $user_string =~ s/IP/$_/rg } @arr1; }

        A better approach would likely be to use a templating engine over your data.

          A reply falls below the community's threshold of quality. You may see it by logging in.
        This is the second program that i created for replacing two argument. But it is getting complex
        use strict; use warnings; use Path::Tiny qw(path); my $filenme='d:\SampleCicoIOSEvent.txt'; my $file=path($filenme); my $data= $file->slurp_utf8; use File::Slurp; my $filename='e:\filename.txt'; my $IPfilename='e:\IPfilename.txt'; my @arr = read_file($filename); my @arr1 = read_file($IPfilename); my @output= map{ $data=~s/C_USERNAME/$_/rg} @arr; my @output1= map{ $data=~s/IP/$_/rg} @arr1; print @output; print @output1;
Re: Need to replace string from external file
by 1nickt (Canon) on Nov 06, 2017 at 11:38 UTC

    Hi, welcome, please show:

    1. sample input (in <code></code> tags)
    2. expected output from that input (in <code></code> tags)
    3. code you have tried (in <code></code> tags)
    4. how it fails (in <code></code> tags if it's an error message)

    see PerlMonks FAQ: Posting on PerlMonks

    The way forward always starts with a minimal test.
      use strict; use warnings; use Path::Tiny qw(path); my $filenme='d:\SampleCiscoIOSEvent.txt'; my $file=path($filenme); my $data= $file->slurp_utf8; use File::Slurp; my $filename='e:\filename.txt'; my @arr = read_file($filename); my @output= map{ $data=~s/C_USERNAME/$_/rg} @arr; print @output;

        Are you copying and pasting this from somewhere? Why are you using File::Slurp when you're already using Path::Tiny?

        Hi, that's helpful, thanks. Please see my post and the links in it, as well as any other well-formed question, for examples of how to post code + input + output.

        It's still not possible to see what the contents of the files are, and what you wish the output to be.


        The way forward always starts with a minimal test.
        Now this is the code for replacing two arguments Sorry for the typo & other stuff i am new to this group ...
        use strict; use warnings; use Path::Tiny qw(path); my $filenme='d:\SampleCicoIOSEvent.txt'; my $file=path($filenme); my $data= $file->slurp_utf8; use File::Slurp; my $filename='e:\filename.txt'; my $IPfilename='e:\IPfilename.txt'; my @arr = read_file($filename); my @arr1 = read_file($IPfilename); my @output= map{ $data=~s/C_USERNAME/$_/rg} @arr; my @output1= map{ $data=~s/IP/$_/rg} @arr1; print @output; print @output1;