How to cut the second column of a string in an array using Perl

Viewed 142

I have below snippet to read command output and feed it into an array(@ret).

my @ret = `$cmd`;
  chomp @ret;
  foreach my $line (@ret)
  {
  print $line;
  }

Here's the $CMD output and the same is written into @ret array.

(154) "1.T" Oct 15, 2020 7:05 AM
(159) "1.S" Oct 14, 2020 7:03 AM
(161) "1.R" Oct 13, 2020 7:03 AM
(163) "1.Q" Oct 11, 2020 7:06 AM
(164) "1.P" Oct 10, 2020 7:06 AM
(166) "1.N" Oct 8, 2020 1:53 AM
(167) "1.K" Oct 5, 2020 7:06 AM
(168) "1.J" Oct 4, 2020 4:44 PM
(169) "1.I" Oct 3, 2020 3:54 PM
(170) "1.H" Oct 3, 2020 7:02 AM

Not sure, how to extract the second column that is enclosed in double quotes, from this output. Can someone help or provide some inputs. Thanks.

5 Answers

You can do this by applying a regex directly to the array:

my @ret = `$cmd`;
s/(^[^"]+")|("[^"]+)//g for @ret;

Basically the regular expression removes everything before the first double quote (including the double quote itself), and everything after the last double quote (included).

Consider the following demo:

my @ret = (
    q/(154) "1.T" Oct 15, 2020 7:05 AM/,
    q/(159) "1.S" Oct 14, 2020 7:03 AM/,
    q/(161) "1.R" Oct 13, 2020 7:03 AM/,
    q/(163) "1.Q" Oct 11, 2020 7:06 AM/,
    q/(164) "1.P" Oct 10, 2020 7:06 AM/,
    q/(166) "1.N" Oct 8, 2020 1:53 AM/,
    q/(167) "1.K" Oct 5, 2020 7:06 AM/,
    q/(168) "1.J" Oct 4, 2020 4:44 PM/,
    q/(169) "1.I" Oct 3, 2020 3:54 PM/,
    q/(170) "1.H" Oct 3, 2020 7:02 AM/,
);

s/(^[^"]+")|("[^"]+)//g  for @ret;
print "$_\n" for @ret;

Yields:

1.T
1.S
1.R
1.Q
1.P
1.N
1.K
1.J
1.I
1.H

Try this:

$line =~ m/"([^"]+)"/;
$secondColumn = $1;

Match non-quote characters between two quotes, and take the first capturing group:

#!/usr/bin/perl

my $str = '(164) "1.P" Oct 10, 2020 7:06 AM';

$str =~ m/"([^"]+)"/;
print $1;

Demo: https://www.ideone.com/HCBrG5

Following code piece parses command's output into hash. Then you can manipulate as your heart desires.

use strict;
use warnings;
use feature 'say';

use Data::Dumper;

my $re = qr/\((\d+)\) "(.+?)" (.*)\z/;
my $data;

while( <DATA> ) {
    chomp;
    my($event,$id,$date) = $_ =~ /$re/;
    $data->{$event} = { id => $id, date => $date };
}

say Dumper($data);

say $data->{$_}{id} for sort { $a <=> $b } keys %{$data};

__DATA__
(154) "1.T" Oct 15, 2020 7:05 AM
(159) "1.S" Oct 14, 2020 7:03 AM
(161) "1.R" Oct 13, 2020 7:03 AM
(163) "1.Q" Oct 11, 2020 7:06 AM
(164) "1.P" Oct 10, 2020 7:06 AM
(166) "1.N" Oct 8, 2020 1:53 AM
(167) "1.K" Oct 5, 2020 7:06 AM
(168) "1.J" Oct 4, 2020 4:44 PM
(169) "1.I" Oct 3, 2020 3:54 PM
(170) "1.H" Oct 3, 2020 7:02 AM

Output

$VAR1 = {
          '168' => {
                     'id' => '1.J',
                     'date' => 'Oct 4, 2020 4:44 PM'
                   },
          '164' => {
                     'date' => 'Oct 10, 2020 7:06 AM',
                     'id' => '1.P'
                   },
          '159' => {
                     'id' => '1.S',
                     'date' => 'Oct 14, 2020 7:03 AM'
                   },
          '166' => {
                     'date' => 'Oct 8, 2020 1:53 AM',
                     'id' => '1.N'
                   },
          '170' => {
                     'date' => 'Oct 3, 2020 7:02 AM',
                     'id' => '1.H'
                   },
          '154' => {
                     'date' => 'Oct 15, 2020 7:05 AM',
                     'id' => '1.T'
                   },
          '169' => {
                     'date' => 'Oct 3, 2020 3:54 PM',
                     'id' => '1.I'
                   },
          '167' => {
                     'date' => 'Oct 5, 2020 7:06 AM',
                     'id' => '1.K'
                   },
          '163' => {
                     'date' => 'Oct 11, 2020 7:06 AM',
                     'id' => '1.Q'
                   },
          '161' => {
                     'date' => 'Oct 13, 2020 7:03 AM',
                     'id' => '1.R'
                   }
        };

1.T
1.S
1.R
1.Q
1.P
1.N
1.K
1.J
1.I
1.H

Just grab what's in quotes!

@ret = map { /"([^"]*)"/ } @ret;
print "$_\n" for @ret;
Related