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

Hi,
this is a repost.
I have lots of files (named *.war". Inside those files, the last 10 chars of the first line are the text to be searched and replaced for all occurrences in the file by the actual filename (without .war). One solution/response was
perl -i~ -pe 'if($ARGV ne $l){$f=$l=$ARGV;$f=~s \.wra//;substr($_,-11) +=$f.$/;}' *
But this gives me error message:
Modification of a read-only value attempted at -e line 1, <> line 1.
After this, the files are empty.

Does anyone know what may be wrong ?

update (broquaint): added formatting

Replies are listed 'Best First'.
Re: Replacing text inside lots of files
by bart (Canon) on Nov 03, 2003 at 10:33 UTC
    Wait a minute... did you accidently use $1, with a one, instead of $l, lower case "L"? Not here, but on your actual command line? These two characters look remarkably alike, to the point it's utterly confusing. My advice: don't ever use "l" (lower case "L") as the name for a variable without a very good reason.

    Use any other name than $l (or rather, $1). It ought to work then. I see no reason why not. Oh, and "wra" looks like another typo to me, just like the lack of a slash between the "s" and the backslash.

    perl -i~ -pe 'if($ARGV ne $z){$f=$z=$ARGV;$f=~s/\.war$//;substr($_,-11 +)=$f.$/;}' *

    update: Hmm... I actually like this better:

    perl -i~ -pe 'if($ARGV ne $z){$f=$z=$ARGV;$f=~s/\.war$//;s/.{10}$/$f/} +' *
    or this:
    perl -i~ -pe 'if($ARGV ne $z){$z=$ARGV; s/.{10}$/$z/; s/\.war$//}' *
      Thanks for the hint regarding the variable name. I tried this example by passing a single filename as argument. The text to be replaced has been found and replaced. But only in the first line of the file. The other occurrences have not been replaced. I use this with "active Perl" in a DOS-Box in Win2k. And using the asterisk gives the error message "Can't open *: Invalid argument".
        Alright, now I get what you're trying to do. Your original post didn't quite make clear that the text was to be replaced everywhere in the file. Try this (formatted for Win32):

        perl -i~ -pe "if($ARGV ne $z){$f=$z=$ARGV;$f=~s/\.wra//;/(.{10})$/; $r +=$1} s/$r/$f/g" *.wra

        Of course, at this point the solution stops looking elegant and cool (not that it ever really did), and there are too many one-letter variables. My recommendation is to invest some time in studying Perl and create a real script to do your modifications.

        The one-liner may be cute and good for obfuscation value, but if you aren't sure what it's doing, it shouldn't go into production/be handed in for your assignment, etc. By the way, this time it's a one, not an el.