user982809
user982809

Reputation: 254

find: missing argument to `-exec' in perl script

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

Answers (4)

jaypal singh
jaypal singh

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

Adam Zalcman
Adam Zalcman

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

JRFerguson
JRFerguson

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

user554546
user554546

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

Related Questions