Reputation: 254
I know there have been a lot of questions similar to my small problem. A few got fixed by a second -exec, but that's not what i need. Maybe i'm just not seeing where my problem really is...
I want to anonymize all IPs in the html-files in my weblog analytics output:
#!/usr/bin/perl
use warnings;
use strict;
use readPathsFromConf;
system ("find $readPathsFromConf::WWWPATH$readPathsFromConf::WWWSUBDIR -type f -name \"\*\" -exec sed -i '' 's/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/anonymisiert/g' \{\} \;");
i only get
find: missing argument to `-exec'
I get the right files on STDOUT when i type this on the commandline:
find /var/www/statistics/ -type f -name "*"
but as soon as i add the exec-part i get the error.
Is something wrong with the Escape Characters? What am i missing? (Please excuse my English)
Upvotes: 3
Views: 3578
Reputation: 77155
This should work -
#!/usr/bin/perl
use warnings;
use strict;
system ("find /var/www/statistics/ -type f -name \"*\" -exec sed -i 's/\\([0-9]\\{1,3\\}\\.\\)\\{3\\}[0-9]\\{1,3\\}/anonymousIP/g' {} +");
Upvotes: 1
Reputation: 27233
You should escape quotes and backslashes embedded in the string:
system ("find /var/www/statistics/ -type f -name \"*\" -exec sed -i 's/\\([0-9]\\{1,3\\}\\.\\)\\{3\\}[0-9]\\{1,3\\}/anonymousIP/g' {} \\;");
Also, note that on some platforms (e.g. Mac OS X) sed's -i
option requires an argument - backup file extension.
Upvotes: 3
Reputation: 7526
Perl has a perfectly good File::Find core module. There is no need to invoke an external utility to use find.
There is even a helper script called find2perl which might help you bridge from using the shell's find to Perl's. This is discussed in the link above.
Upvotes: 3
Reputation:
Because in:
system ("find /var/www/statistics/ -type f -name "*" -exec sed -i 's/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/anonymousIP/g' {} \;");
The double quotes around the asterisk aren't escaped. So, the interpreter thinks you're multiplying two things, and will automatically convert each of the strings to 0
(incidentally, this is also why you don't use ==
for string comparisons in Perl).
For example, the one-liner
perl -e 'use strict;use warnings;my $a="abc";my $b="def";my $c=$a*$b;print "$c\n";'
produces the output
Argument "def" isn't numeric in multiplication (*) at -e line 1.
Argument "abc" isn't numeric in multiplication (*) at -e line 1.
0
Since you have strict
and warnings
enabled, you too should have seen analogous warnings to those given above.
More importantly, however: if your script consists of a system
call, why not just run the argument to system
directly on the command line?
Upvotes: 1