(jeffa) Re: Can you teach a new dog an old trick?
by jeffa (Bishop) on Jul 28, 2001 at 20:39 UTC
|
perl -i.bak -pe 's/string1/string2/g' *.htm
This changes all occurrences of the literal string,
'string1' with 'string2' in all .htm files and makes
backups at the same time.
jeffa
| [reply] [d/l] |
Re: Can you teach a new dog an old trick?
by bikeNomad (Priest) on Jul 28, 2001 at 20:40 UTC
|
It's such a common idiom that the -p and -i command-line flags were invented to deal with it: #!/usr/bin/perl -wpi
s/string1/string2/g;
And then you'd run it as: myScript *.htm
update: note that the contents of a script run with -p or -n are inside a loop. If you want to initialize anything before the loop, use a BEGIN or INIT block. | [reply] [d/l] [select] |
|
This is not good...
I tried to extend it to:
#!/usr/bin/perl -wpi
my $src = shift;
my $dst = shift;
s/$src/$dst/g;
and it throws many many messages on me:
Use of uninitialized value in substitution (s///) at /home/rj/bin/repl
+ace line 4, <> line 38.
Use of uninitialized value in regexp compilation at /home/rj/bin/repla
+ce line 4, <> line 39.
Use of uninitialized value in substitution (s///) at /home/rj/bin/repl
+ace line 4, <> line 39.
Use of uninitialized value in regexp compilation at /home/rj/bin/repla
+ce line 4,
(called "replace hallo hello tmp.txt")
Then I looked at man perl what this switch -p does
ok it was not there, so I looked at man perlrun and
then I found the error (it tries to get $src and $dst in every
loop.
Well, I´m using my old replace script now again...
#!/usr/bin/perl
my $src = shift;
my $dst = shift;
print "Replace >$src< with >$dst<.\n";
$dst =~ s/\\n/\n/g;
$dst =~ s/\\t/\t/g;
foreach $file (@ARGV) {
my $file2 = "/tmp/$file.".$$;
print "replacing in File: $file...\n";
print "$file2\n";
open HANDLE, $file or die "$file: $!";
while(<HANDLE>) {
$zeile .= $_; # Zeile von Datei einlesen
}
close HANDLE;
$zeile =~ s/$src/$dst/gs;
open HANDLE, ">$file2";
print HANDLE $zeile;
close HANDLE;
$zeile = '';
system("mv $file2 $file");
}
Its ugly and unelegant and made 1996, but it works. :-)
Ciao
| [reply] [d/l] [select] |
|
#!/usr/bin/perl -wpi
BEGIN { ($src,$dst)=(@ARGV); }
s/$src/$dst/g;
| [reply] [d/l] |
Re: Can you teach a new dog an old trick?
by Chady (Priest) on Jul 28, 2001 at 20:39 UTC
|
perl -pi.bak -e "s/string1/string2/g" *
run this and it will open all files in the current directory with the inplace file edit -i and files are backed up to .bak extensions, the -p assumes that there is a while loop over the file so all you need to do is run the substitution within a -e switch and you're done with it.
Update: I stole from jeffa's post that you should have *.htm instead of * so it won't eat all the files
He who asks will be a fool for five minutes, but he who doesn't ask will remain a fool for life.
Chady | http://chady.net/ | [reply] [d/l] [select] |
Re: Can you teach a new dog an old trick?
by Anonymous Monk on Jul 28, 2001 at 23:34 UTC
|
| [reply] [d/l] |
Re: Can you teach a new dog an old trick?
by Anonymous Monk on Jul 29, 2001 at 02:28 UTC
|
why not simply the command line usage---
perl -p -i -e 's/oldstring/newstring/g' filename(s)
| [reply] |
Re: Can you teach a new dog an old trick?
by John M. Dlugosz (Monsignor) on Jul 30, 2001 at 02:49 UTC
|
Other's have shown how to use -i, -p, -n, etc. But I wanted to point out another issue.
I use a program called tcgrep, which is a grep clone written in Perl by Tom Christenson. I've updated it to do its own globbing in Windows platforms. I don't know if that does replacements... but, being such a common thing, I'll bet an egrep or whatever exists too, that does this with lots of fancy and subtle features.
| [reply] |
Re: Can you teach a new dog an old trick?
by Anonymous Monk on Jul 29, 2001 at 23:22 UTC
|
perl -pi.bak -e 's/string1/string2/g' *.htm
Use double quotes on Windows. | [reply] [d/l] |
Re: Can you teach a new dog an old trick?
by Anonymous Monk on Jul 30, 2001 at 17:29 UTC
|
#!/usr/bin/perl -p -i
s/string1/string2/g;
run this as
./script *.htm
| [reply] |
Re: Can you teach a new dog an old trick?
by mischief (Hermit) on Jul 30, 2001 at 23:19 UTC
|
The only change I would make is to add this line:
die "file already exists\n" if -e "tmp"
at the top, just to avoid clobbering any existing tmp files or directories or whatever.
| [reply] [d/l] |
|
Could the code to recurse through sub directories, processing all the *.html be added in only a few lines?
| [reply] |
|
use strict;
use File::Find;
find(
sub {
return unless -f $_ and /\.html?$/;
# do your funky thang
},
shift || '.'
);
That is, recurse starting from the directory given on the command line, or the current directory if nothing is specified. Then, only for directory entries that are files whose extension is .htm or .html, do whatever makes you happy.
--g r i n d e r
| [reply] [d/l] |
|
My dirty code for descending subdirectories used the unix
find command to generate a list of files to be
acted on. In my case, to chmod files.
%perl -e '@list = `find . -name "*.htm"`; foreach (@list) {`chmod 644
+$_`}'
| [reply] [d/l] [select] |
|
|
|
|