How to grep for an exact string match with Perl

Written by - 0 comments

Published on - last updated on August 7th 2023 - Listed in Perl Coding


Inside a Perl script I wanted to compare an input string ($ARGV[0]) against an array of strings. When the input exactly matches against one of the array items, then print that a match was found.

For this purpose, the Perl-internal grep function (similar in behaviour to the grep Shell command, but not exactly the same) can be used. To grep for an exact match (eq) compared to a list of array, the following (simplified) code was created:

ck@mint /tmp $ cat grep1.pl
#!/usr/bin/perl
my @string_list = ();
my $input = $ARGV[0];
push @string_list, 'Timeout';
push @string_list, 'Error';
push @string_list, 'Warning';

if (grep { $input eq $_} @string_list) {
  print "Input ($input) matched against our string list\n";
} else {
    print "Input DID NOT match anything\n";
}

According to the Perl grep documentation, the $_ variable represents each entry of the list:

Evaluates the BLOCK or EXPR for each element of LIST (locally setting $_ to each element) and returns the list value consisting of those elements for which the expression evaluated to true.

The Perl script now returns whether or not the input string matches one of the elements:

ck@mint /tmp $ ./grep1.pl "Facebook"
Input DID NOT match anything
ck@mint /tmp $ ./grep1.pl "Twitter"
Input DID NOT match anything
ck@mint /tmp $ ./grep1.pl "Error"
Input (Error) matched ignore list

And (important to the use of this script) is that only an exact match works. An input which contains (but not exactly matches) an entry of the @string_list should not trigger a match:

ck@mint /tmp $ ./grep1.pl "Error"
Input (Error) matched ignore list
ck@mint /tmp $ ./grep1.pl "Error occurred"
Input DID NOT match anything

Alternative exact string comparison using 'any'

As pointed out in comments on my Mastodon toot, another alternative would be to use the 'any' function, which is part of List::Util module. The following code can be used:

ck@mint /tmp $ cat any.pl
#!/usr/bin/perl
use List::Util 'any';
my @string_list = ();
my $input = $ARGV[0];
push @string_list, 'Timeout';
push @string_list, 'Error';
push @string_list, 'Warning';

if (any { $input eq $_} @string_list) {
  print "Input ($input) matched against our string list\n";
} else {
    print "Input DID NOT match anything\n";
}

The same exact string comparison and matching works here:

ck@mint /tmp $ perl any.pl "Error"
Input (Error) matched against our string list

ck@mint /tmp $ perl any.pl "Error, test"
Input DID NOT match anything

According to a benchmark, using 'any' is much faster than 'grep'.

However this only works if you have at least version 1.33 of the List::Util Perl module installed. On a RHEL 7 machine with Perl 5.16 and without manually updated modules using CPAN you will most likely run into such an error:

ck@rhel7 /tmp $ perl any.pl "Error"
"any" is not exported by the List::Util module
Can't continue after import errors at any.pl line 2.
BEGIN failed--compilation aborted at any.pl line 2.

Starting with Perl 5.20, List::Util 1.33 should be bundled and should therefore work without the need of installing an additional module.


Add a comment

Show form to leave a comment

Comments (newest first)

No comments yet.

RSS feed

Blog Tags:

  AWS   Android   Ansible   Apache   Apple   Atlassian   BSD   Backup   Bash   Bluecoat   CMS   Chef   Cloud   Coding   Consul   Containers   CouchDB   DB   DNS   Database   Databases   Docker   ELK   Elasticsearch   Filebeat   FreeBSD   Galera   Git   GlusterFS   Grafana   Graphics   HAProxy   HTML   Hacks   Hardware   Icinga   Influx   Internet   Java   KVM   Kibana   Kodi   Kubernetes   LVM   LXC   Linux   Logstash   Mac   Macintosh   Mail   MariaDB   Minio   MongoDB   Monitoring   Multimedia   MySQL   NFS   Nagios   Network   Nginx   OSSEC   OTRS   Office   OpenSearch   PGSQL   PHP   Perl   Personal   PostgreSQL   Postgres   PowerDNS   Proxmox   Proxy   Python   Rancher   Rant   Redis   Roundcube   SSL   Samba   Seafile   Security   Shell   SmartOS   Solaris   Surveillance   Systemd   TLS   Tomcat   Ubuntu   Unix   VMWare   VMware   Varnish   Virtualization   Windows   Wireless   Wordpress   Wyse   ZFS   Zoneminder