Sridhar Sarnobat
Sridhar Sarnobat

Reputation: 25236

Execute module-qualified function inside perl regex substitution?

I have the following perl one-liner to convert /path/to/file.txt to /path/to/

echo "/path/to/file.txt" | perl -pe 's{(.*)}{File::Basename->dirname($1)}ge' 

but I'm missing something in my invocation of File::Basename->dirname(), causing the following error:

Can't locate object method "dirname" via package "File::Basename" (perhaps you forgot to load "File::Basename"?) at -e line 1, <> line 1.

What am I missing?

(I know I can just use dirname from bash but I'm trying to do something more complicated with perl than what this stripped down example shows).

Upvotes: 0

Views: 384

Answers (3)

zdim
zdim

Reputation: 66883

Load a module with -MModName=func

perl -MFile::Basename=dirname -pe 's{(.*)}{dirname($1)}ge' 

The File::Basename module exports all its functions by default so you don't need =dirname above. But this varies between modules, and mostly you do need to import symbols. For more on how to do that in a one-liner, find the -M switch in Command Switches in perlrun.

Upvotes: 1

ikegami
ikegami

Reputation: 385764

Error #1:

Like the message suggests (perhaps you forgot to load "File::Basename"?), you need to load File::Basename.

perl -pe'use File::Basename; ...' 

or

perl -MFile::Basename -pe'...' 

Error #2:

dirname is not a method, so File::Basename->dirname is incorrect. It needs to be called as File::Basename::dirname.

perl -MFile::Basename -pe's{(.*)}{File::Basename::dirname($1)}ge' 

You could also import dirname.

perl -MFile::Basename=dirname -pe's{(.*)}{dirname($1)}ge' 

Fortunately, File::Basename exports dirname by default, so you can simply use

perl -MFile::Basename -pe's{(.*)}{dirname($1)}ge' 

Upvotes: 1

Borodin
Borodin

Reputation: 126722

The problem was that you had <button> in the replacement string, but you've removed that now so it should work

The replacement string must be a valid Perl expression if you're using the /e modifier, and

<button>File::Basename->dirname($1)

isn't valid Perl


The correct command would be:

echo "/path/to/file.txt" | perl -pe 'use File::Basename 'dirname'; s{([^\n]+)}{dirname($1)}ge' 

Upvotes: 0

Related Questions