-1

Have a logfile my_file.txt which I know has the following structure:

milk marta 1231 joe 1223 ralph 7C3D
cookie
jam
milk marta 163 joe 23 ralph 7FFF

And what I want to do is extract with the help of regex in perl all the values of lines that start with the delimiter milk (which I know beforehand). Then I know I will have a number of value names (in the toy example marta, joe, ralph), each followed by a decimal or hexadecimal value.

  • Is there a way to read the values without knowing beforehand if they are decimal or hex?

  • What is the best way to store this values? I thought of doing a hash with the keys being marta, joe, ralph, but I might not know them beforehand, meaning I will know all of them once I have read the first line, not before.

And here comes my attempt so far

$my_file = "my_file.txt"
open my $fh, $my_file or die "Nope!"

while (my $line = <$fh>)
{
    if ($line =~ m/milk/)
    {
        # here iterate with a for or while loop over the $line
        # and read word and value
    }
}
titus.andronicus
  • 517
  • 1
  • 7
  • 19
  • 1
    `163` - is that decimal or hex? Unclear what you're asking. Pls clarify. – rustyx Aug 30 '16 at 14:52
  • 1
    It is impossible to know if a given string of characters is a decimal or hexadecimal number. If it contains the characters A-F then you can be sure that it's hexadecimal (assuming decimal and hexadecimal are your only options). But what about 1234? Is that decimal 1234 or hexadecimal 4660? There's no way to be sure. – Dave Cross Aug 30 '16 at 14:53

2 Answers2

2

Aside from the issue of determining whether a digit string is decimal or hex, something like this will extract the text that you need

use strict;
use warnings 'all';

use Data::Dump 'dd';

my @data;

while ( <DATA> ) {
    my ($col1, %item) = split;
    push @data, \%item if $col1 eq 'milk';
}

dd \@data;

__DATA__
milk marta 1231 joe 1223 ralph 7C3D
cookie
jam
milk marta 163 joe 23 ralph 7FFF

output

[
  { joe => 1223, marta => 1231, ralph => "7C3D" },
  { joe => 23, marta => 163, ralph => "7FFF" },
]
Borodin
  • 126,100
  • 9
  • 70
  • 144
1

OK, what I'd do is something like this:

if ($line =~ /^milk/) {
    my %names = ($line =~ /(\w+)\s+([a-f\d]+)/gi);

    use Data::Dumper;
    print Dumper \%names;
}

What it'll do is first ensure the line starts with milk, and then grab every pair of single word and hex number in the line and dump each pair to an array.

Sebastian Lenartowicz
  • 4,695
  • 4
  • 28
  • 39