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
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.
No comments yet.
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