Paul IT
Paul IT

Reputation: 85

Not able to understand a command in perl

I need help to understand what below command is doing exactly

$abc{hier} =~ s#/tools.*/dfII/?.*##g;

and $abc{hier} contains a path "/home/test1/test2/test3"

Can someone please let me know what the above command is doing exactly. Thanks

Upvotes: 1

Views: 80

Answers (3)

AnFi
AnFi

Reputation: 10913

$abc{hier} =~ s#/tools.*/dfII/?.*##g;

The above commands use regular expression to strip/remove trailing /tools.*/dfII and /tools.*/dfII/.* from value of hier member of %abc hash.

It is pretty basic perl except non standard regular expression limiters (# instead of standard /). It allows to avoid escaping / inside the regular expression (s/\/tools.*\/dfII\/?.*//g).

My personal preferred style-guide would make it s{/tools.*/dfII/?.*}{}g .

Upvotes: 2

Yunnosch
Yunnosch

Reputation: 26763

This =~ means "Do a regex operation on that variable."

(Actually, as ikegami correctly reminds me, it is not necessarily only regex operations, because it could also be a transliteration.)

The operation in question is s#something#else#, which means replace the "something" with something "else".

The g at the end means "Do it for all occurences of something."
Since the "else" is empty, the replacement has the effect of deleting.

The "something" is a definition according to regex syntax, roughly it means "Starting with '/tools' and later containing '/dfII', followed pretty much by anything until the end."

Note, the regex mentions at the end /?.*. In detail, this would mean "A slash (/) , or maybe not (?), and then absolutely anything (.) any number of times including 0 times (*). Strictly speaking it is not necessary to define "slash or not", if it is followed by "anything any often", because "anything" includes as slash, and anyoften would include 0 or one time; whether it is followed by more "anything" or not. I.e. the /? could be omitted, without changing the behaviour. (Thanks ikeagami for confirming.)

Upvotes: 2

Dave Cross
Dave Cross

Reputation: 69314

s/PATTERN/REPLACEMENT/ is Perl's substitution operator. It searches a string for text that matches the regex PATTERN and replaces it with REPLACEMENT.

By default, the substitution operator works on $_. To tell it to work on a different variable, you use the binding operator - =~.

The default delimiter used by the substitution operator is a slash (/) but you can change that to any other character. This is useful if your PATTERN or your REPLACEMENT contains a slash. In this case, the programmer has used # as the delimiter.

To recap:

$abc{hier} =~ s#PATTERN#REPLACEMENT#;

means "look for text in $abc{hier} that matches PATTERN and replace it with REPLACEMENT.

The substitution operator also has various options that change its behaviour. They are added by putting letters after the final delimiter. In this case we have a g. That means "make the substitution global" - or match and change all occurrences of PATTERN.

In your case, the REPLACEMENT string is empty (we have two # characters next to each other). So we're replacing the PATTERN with nothing - effectively deleting whatever matches PATTERN.

So now we have:

$abc{hier} =~ s#PATTERN*##g;

And we know it means, "in the variable $abc{hier}, look for any string that matches PATTERN and replace it with nothing".

The last thing to look at is the PATTERN (or regular expression - "regex"). You can get the full definition of regexes in perldoc perlre. But to explain what we're using here:

  • /tools : is the fixed string "/tools"
  • .* : is zero or more of any character
  • /dfII : is the fixed string "/dfII"
  • /? : is an optional slash character
  • .* : is (again) zero or more of any character

So, basically, we're removing bits of a file path from a value that's stored in a hash.

Upvotes: 3

Related Questions