Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Format perl regex capture groups

Tags:

regex

bash

perl

Consider the following situation. It is hypothetical, but demonstrates a general thing I would like accomplished.

Suppose I have a file, which has one or more lines. On each line, it may have one or more instances of [name]=[value], where [name] is some variable name and [value] is some value. Suppose further that each of these are matched by /[a-zA-Z]+=[0-9]+/.

What I would like is a perl expression that will print out each match, formatted in a particular way. My intent is to use this on the command line to parse data from files. A hypothetical solution, made invalid because perl doesn't actually accept this syntax: print m/([a-zA-Z]+)=([0-9]+)/name: \1, value: \2\n/g, which, when run on each line, in our ideal world, would print out each match from each line like name:[name], value:[value], each formatted match on its own line.

For example, consider this input file test.txt:

blah blah count=5 blah i=1
books=2 blah
blah fairies=87 water=0

Suppose we then type our magic command into bash, something like the following:

perl -n -e 'print m/([a-zA-Z]+)=([0-9]+)/name: \1, value: \2\n/g' test.txt

(It might be more reasonable to require some kind of loop over all returned matches, but hopefully you get the idea.)

It would print the following:

name: count, value: 5
name: i, value: 1
name: books, value: 2
name: fairies, value: 87
name: water, value: 0

I realize that this syntax does not actually work, but I would like to accomplish the same thing in as brief a piece of perl as possible. I hope to be able to use it occasionally on the command line to find and format text. I've written my own ruby script, but its a bit buggy, and not included in a standard environment (or in anybody's environment but my own). Anybody know some perl secrets?

like image 632
Erhannis Avatar asked Dec 15 '22 10:12

Erhannis


2 Answers

You were pretty close. ;-)

$ perl -ne 'print "name: $1, value: $2\n" while /([a-zA-Z]+)=([0-9]+)/g;' test.txt
name: count, value: 5
name: i, value: 1
name: books, value: 2
name: fairies, value: 87
name: water, value: 0

Edit: since your comment seemed to indicate that shorter is better, here's a version with a few characters shaved off:

$ perl -lne 'print "name: $1, value: $2" while /([A-Z]+)=(\d+)/gi' test.txt
like image 132
Matt Jacob Avatar answered Jan 04 '23 06:01

Matt Jacob


My suggestion would be - consider selecting your vars into a hash.

use Data::Dumper;
local $/;
my %stuff = <> =~ m/(\w+)=(\d+)/g;
print Dumper \%stuff ;

Should do approximately what you want.

like image 32
Sobrique Avatar answered Jan 04 '23 05:01

Sobrique