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

Hi there! Sorry I am really new in perl, but maybe you can help me out? Just tried to replace a string called "test" by "replace" in a txt file. I executed it in windows(skript below) and in unix(with different path). Result was, that he is not showing any error, but also not doing anything. What did I do wrong? Text File name is just a.txt and perl skript is a.pl a.txt includes: test a.pl (in windows) says: ########################################################
#!/usr/bin/perl use strict; my $S="C:Users\name\Desktop\a.txt"; open(FILE, "<$S") || die "File not found"; my @lines = <FILE>; close(FILE); my @newlines; foreach(@lines) { $_ =~ s/<test>/replace/g; push(@newlines,$_); } open(FILE, "$S") || die "File not found"; print FILE @newlines; close(FILE); #################################################
Can you help me out on that? I am so desperate :-( Thanks in advance!

Replies are listed 'Best First'.
Re: no reaction on string replace
by kcott (Archbishop) on Sep 10, 2013 at 20:53 UTC

    G'day semipro,

    Welcome to the monastery.

    Please add <code>...</code> tags around your posted code: it's very hard to read as is.

    You problem is probably this line:

    my $S="C:Users\name\Desktop\a.txt";

    Characters prefixed with a backslash inside double-quotes have a special meaning. See perlop: Quote and Quote-like Operators and perlop: Quote-Like Operators.

    You can fix this by either doubling up the backslashes:

    my $S="C:Users\\name\\Desktop\\a.txt";

    or simply using single-quotes instead:

    my $S='C:Users\name\Desktop\a.txt';

    I don't use MSWin much, but I think you have an additional problem with C:Users: should that be C:\Users?

    -- Ken

Re: no reaction on string replace
by Eily (Monsignor) on Sep 10, 2013 at 20:57 UTC

    You should use warnings; Because the default for filehandle is *input*. So when you write open(FILE, "$S") you open the file for reading. You should have been warned about that.

    @lines = <FILE> makes a copy of the file content, but for(@lines) doesn't make any copy, inside the for loop $_ is not a copy of a line, it's the line itself. So in the end @lines and @newlines are certainly the same.

      Hi, thnx! i put the warnings on. While xecuting the cmd interface tells me if he can not find a file. But he can, so the a.txt file adress should be ok. bīBut there is still no effect and no warnings. Your comment on the @ lines sounds convenient, so finally he is copying the old line in the new line and nothing is happening? How can I fix that issue? And here (sorry not the original but the same principle)the code (which has no effect):
      #!/usr/bin/perl -w use strict; my $SCU='C:/Users/name/Desktop/a.txt'; open(FILE, "<$SCU") || die "File not found"; my @lines = <FILE>; close(FILE); my @newlines; foreach(@lines) { $_ =~ s/<ABCD>/xyz/g; push(@newlines,$_); } open(FILE, "$SCU") || die "File not found"; print FILE @newlines; close(FILE);

        You should edit your first post instead of posting your code again. The editing area should appear just below your original post.

        About your posted-again code, there's still no > in your second open, so you can't write on the file. Write open (FILE, ">", "$SCU") or die "Could not open file $SCU: $!";. $! is a special var that contains the error that occurred while trying to open your file.

        If you do not want to modify the output of @lines in your for loop, you can either make an explicit copy with my $copy = $_; or, if you use a recent version of Perl, use the /r switch on the substitution, which means that the result is returned, and the original variable is not affected. If you do not write $var =~ s/pattern/replace/; but just s/pattern/replace; it works on $_ by default BTW. So in your case you could write (if you get an error, your version of Perl is probably too old):  push @newlines, s/<ABCD>/xyz/rg for @lines;

Re: no reaction on string replace
by Laurent_R (Canon) on Sep 10, 2013 at 21:13 UTC

    Another possible approach is a Perl one-liner at the DOS command line:

    perl -pi.bak -e "s/test/replace/g;" filename.txt

    Try it with unimportant test files first. The replacements will occur in the existing file, and the old contents should be saved to a .bak file.

      Hi, thnx. Yeah thats working!!! cool
      Hi, ok I was bit early ecouraged. the line  perl -pi.bak -e "s/test/replace/g;" filename.txt works as DOS command. But when I try to squeez it in my skript he needs an operator before the file path. So
      #!/usr/bin/perl -w perl -pi.bak -e "s/test/replace/g;" C:/user/Desktop/filename.txt
      is not working. Can you help me out, again? Thank you!

        Yeah, on the DOS or UNIX command line, the "-pi.bak -e" options have the effect of considerably simplifying the syntax for modifying a text file.

        If you want to write a real script, it is slightly more complicated, those simplifications no longer apply.

        Within a Perl script, you would need to do something like this;

        #!/usr/bin/perl; use strict; use warnings; my $file_in = shift; open my $FH, "<", $file_in or die "cannot open $file_in $!"; while (<$FH>) { s/test/replace/g; print; }

        The above might still be considered simplistic, it is just giving an idea. Please don't hesitate to ask if you need further information.

Re: no reaction on string replace
by toolic (Bishop) on Sep 10, 2013 at 20:38 UTC