http://qs321.pair.com?node_id=1197380

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

I have a problem with the sed command in perl system( q {sed -i — "s/SOL..............*/SOL $sol1/g" topol1.top}); this is the command that i have. I know that i should use double coat and backslash for the variable to be run. But it cant be run and if it is the variable cant be printed. How should I use it?

Replies are listed 'Best First'.
Re: sed command with variable in perl
by AnomalousMonk (Archbishop) on Aug 14, 2017 at 21:40 UTC

    Long (very long) version. Use regexen. File process_file_1.pl:

    This has all the bells and whistles. Shorter versions (including a one-liner) are possible depending on your exact needs. BTW: What version of Perl are you using?

    Usage session:

    Please see perlre, perlretut, and perlrequick for (lots and lots of) regex info. See also perlop (update: specifically, the Regexp Quote-Like Operators section) for discussion of the  s/// substitution operator.


    Give a man a fish:  <%-{-{-{-<

Re: sed command with variable in perl
by ww (Archbishop) on Aug 14, 2017 at 20:07 UTC

    Short version (it's all I have time for): don't. Use regexen. When you're using perl, shelling out is an expensive and unnecessary option in most cases.

    It looks as tho you should read about regexen -- and specifically, substitution -- in a tutorial right here; that is, in the Tutorials section.

      I did not recognize he word 'regexen' as simply the plural of 'regex'. A search revealed that it is a correct, possibly even preferred, form. An explanation (or reference) would have been a big help.
      Bill
Re: sed command with variable in perl
by samira_saber (Novice) on Aug 15, 2017 at 18:28 UTC

    dear AnomalousMonk ;

    thank you for your time. But it is not working in perl. I down know why? Shoudl i jusy replace my file name and i omitted the line for the $sol.because before that i read the variable from the text file and print it and it worked.any other point?

    use strict; use warnings; die "usage: perl $0 file.name \n" unless @ARGV;; my $filename_in = "topol1.top"; print "processing '$filename_in' \n"; my $filename_out = "$filename_in.new"; open my $fh_in, '<', $filename_in or die "opening '$filename_in': $! +"; open my $fh_out, '>', $filename_out or die "opening '$filename_out': $ +!"; while (<$fh_in>) { s{ (SOL) [^\n]* }{$1 $sol1}xmsg; print $fh_out $_ or die "writing '$filename_out': $!"; } close $fh_in or die "closing '$filename_in': $!"; close $fh_out or die "closing '$filename_out': $!"; rename $filename_in, "$filename_in.bak" or die "renaming '$filename_in +': $!"; rename $filename_out, $filename_in or die "renaming '$filename_ou +t': $!";

    2017-08-16 Athanasius added code tags

      Hi samira_saber. First things first: Please edit your reply to add code tags around your code! Please see Markup in the Monastery and Writeup Formatting Tips; also see How do I change/delete my post? for general node-editing etiquette.

      Some comments (in no particular order):

      • ... it is not working ...
        This is almost useless as a problem description. What is "it"? Is it the code you have posted? How does it not work? Is there an error or warning message or messages? Under what conditions of input, etc., etc.? (Later in your reply you write "... before that i read the variable from the text file and print it and it worked." I don't understand this statement, especially in the context of your statement that "it" is not working.)
      • The code in your reply does not have the lines
            use warnings;
            use strict;
        at the start of the source code. These provide very important support and protection for a novice Perler — and for elder Monks as well; I rarely write write a Perl program without using them. See warnings and strict. Use of these modules (called pragmas by convention) is referred to as "enabling warnings and strictures."
      • Your code statement
            my $filename_in = "topol1.top";
        means you are hard-coding the input file name, whereas I was taking the file name from a command line argument. Indeed, the code still requires at least one command line argument (assumed to be the file name) to be present when the script is invoked; the statement
            die "usage: perl $0 file.name \n" unless @ARGV;
        enforces this (see perlvar for info on the  @ARGV array).
      • ... i omitted the line for the $sol.
        In my original code, the my variable  $sol1 holds the string to be substituted in the  s/// substitution operation.
            s{ (SOL) [^\n*] }{$1 $sol1}xmsg;
        I don't understand the point of the substitution operation without something to substitute. Further, if strictures had been enabled (again, see strict), the code would not even compile without this variable being defined and in scope. Even without strictures enabled, warnings would have complained (a run-time warning, not a fatal error) if an undeclared variable having an undefined value had been used — if warnings had been enabled.
      • ... it is not working ... I down know why ...
        This is always useful: Basic debugging checklist.

      I hope these comments will be helpful. If you have any questions, please don't hesitate to ask.


      Give a man a fish:  <%-{-{-{-<

        Hi AnomalousMonk

        ....... using warning; first of all , i used that line before ( use strict; use warning;) at the top of my Perl code and for this reason I omit them. I think i should explain a little bit about my code. I have to m file (from matlab) and I just want to make them work automate as a software. I am very very new into Perl. For this reason I used linux shell commands and it worked fine. Now , There is problem with my code.

        .... File name argument I will put my file name in the correct place , thank you.

        ..... substitution operation without something to substitute As i mentioned before, I have two files each of them has spciefic SOL number which I used grep command to count them and then use it as a variable. $cmd =("grep -e HW1 myhalf1.pdb | wc -l > text1.txt") ; open FILE, "<text1.txt"; my $sol1= do {local $/; <FILE>}; print p ("sol1=$sol1"); As you see I have it before. in the code, which you had posted i just omit this line my $sol1 = 'my new stuff'; because i introduce my variable before. and the next line which have $sol1 is remained intact. s{ (SOL) ^\n* }{$1 $sol1}xmsg;

        ......about errors i ve added the code into my .pl file and run it. After that I check error_log file in the server and there is no warning. I have just changed the line into this my $filename_in = 'topol1.top'; no error.even not making another file. and i ve checked the file permission too.no problem about the permission.