CBlew
CBlew

Reputation: 721

Match multiline pattern in bash using Perl on macOS

On macOS, using built-in bash, I need to match two words on two consecutive lines within a file, say myKey and myValue.

Example file:

<dict>
    <key>myKey</key>
    <string>myValue</string>
</dict>

I already have a working command for substituting a value in such a pair using perl:

perl -i -p0e 's/(<key>myKey<\/key>\s*\n\s*<string>).+(<\/string>)/$1newValue$2/' -- "$filepath"

Question is, how do I simply find whether the file contains that key/value pair, without substituting anything, or, more to the point, just get to know, whether any substitution was made?

EDIT:

  1. Within replacement pattern: \1 -> $1.
  2. Added clarification to the question.

Upvotes: 1

Views: 283

Answers (1)

zdim
zdim

Reputation: 66901

For the basic question you only need to change the substitution operator to the match operator, and print conditionally on whether it matches or not. This can also be done with substitution.

However, since this is in a bash script you can also exit from the perl program (one-liner) with a code that indicates whether there was a match/substitution; then the script can check $?.

To only check whether a pattern is in a file

perl -0777 -nE'say "yes" if /pattern/' -- "$file"

The -0777, that "slurps" the whole file (into $_), is safer than -0 which uses the null byte as records separator. Also, here you don't want -i (change file in place) and want -n (loop over records) instead of -p (also prints each). I use -E instead of -e to enable (all) features, for say. See all this in perlrun.

Inside a shell script you can use the truthy/falsy return of the match operator in exit

perl -0777 -nE'exit(/pattern/)' -- "$file"
# now check $? in shell

where you can now programatically check whether the pattern was found in the file.

Finally, to run the original substitution and be able to check whether any were made

perl -i -0777 -pe'exit(s/pattern/replacement/)' -- "$file"
# now check $? in shell

where now the exit code, so $? in the shell, is the number of substitutions made.

Keep in mind that this does abuse the basic success/failure logic of return codes.

See perlretut for a regex tutorial.

Upvotes: 3

Related Questions