Return only matches from substitution in Perl 5.8.8 (was: Perl “p” regex modifier equivalent)
Question
I've got a script (source) to parse svn info
to create a suitable string for Bash's $PS1
. Unfortunately this doesn't work on one system I'm using which is running Perl 5.8.8 - It outputs all lines instead of only the matches. What would be the Perl 5.8.8 equivalent to the following?
__svn_ps1()
{
local result=$(
svn info 2>/dev/null | \
perl -pe 's;^URL: .*?/((trunk)|(branches|tags)/([^/]*)).*;\2\4 ;p')
if [ -n "$result" ]
then
printf "${1:- (%s)}" $result
fi
}
The output from Perl 5.10 contains only a space, parenthesis, one of branch name, tag name or trunk
, and the end parenthesis. The output from Perl 5.8.8 (without the final p
) contains this plus a parenthesized version of each space-separated part of the svn info
output.
A possible workaround involves a simple grep '^URL: '
between the svn
and perl
commands, but I was hoping to avoid that since this will be executed for each Bash prompt.
Solution
If you only want output from a line that matches, don't use the -p
command-line switch. It prints the value of $_
at the end of each loop. You might want something with the -n
command-line switch:
perl -ne 'print if s/.../.../'
I'd do it in the same way for Perl v5.8 and v5.10. I'm not sure what you think the /p
modifier is doing since you don't use the $`
, $&
, or $'
variables or their per-match equivalents.
You can read about the command-line switches in perlrun.
OTHER TIPS
As of perl 5.10, the /p
switch tells perl to put matched content into ${^PREMATCH}
, ${^MATCH}
and ${^POSTMATCH}
.
And the one-liner you've posted never uses those vars, so omit the /p
.
UPDATE: Trying to keep up with the initial question...
perl -ne 's/search/replace/ and print'
Will only print lines for which the replacement was made. Note -n
versus -p
switch. Also, I've tried the -p
/p
combo on my 5.10 and it happily prints unaltered non-matching lines too. Maybe I missed something...