Home: Perl Programming Help: Intermediate:
How correctly split complicated string



digioleg54
User

Mar 29, 2017, 12:37 PM


Views: 7466
How correctly split complicated string

In Perl script, using shell command I got the line:
USED SPACE Filesystem 1024-blocks Free %Used Iused %Iused Mounted on
/dev/expdatalv 408944640 366194628 11% 114292 1% /export/data

How can I get fifth position: 1142921? How to split it?


FishMonger
Veteran / Moderator

Mar 29, 2017, 1:32 PM


Views: 7463
Re: [digioleg54] How correctly split complicated string

http://perldoc.perl.org/functions/split.html


BillKSmith
Veteran

Mar 29, 2017, 9:44 PM


Views: 7452
Re: [digioleg54] How correctly split complicated string

Or you could use a regex:

Code
use strict; 
use warnings;
$_ = "USED SPACE Filesystem 1024-blocks Free %Used Iused %Iused Mounted on \n"
. "/dev/expdatalv 408944640 366194628 11% 114292 1% /export/data\n"
;

print m/^ ^ (?: [^\s]+ \s ){4} (\d+)/xms;

OUTPUT:
114292

Good Luck,
Bill


digioleg54
User

Mar 30, 2017, 5:58 AM


Views: 7445
Re: [BillKSmith] How correctly split complicated string

I have
my $dsk_used=`df -k . | grep -v -i CAPACITY`;
in $dsk_used I have
USED SPACE Filesystem 1024-blocks Free %Used Iused %Iused Mounted on
/dev/expdatalv 408944640 366194196 11% 114292 1% /export/data

$_ = $dsk_used;
print m/^ ^ (?: [^\s]+ \s ){4} (\d+)/xms;

output - noting
should I do something like

$_ = ~ m/^ ^ (?: [^\s]+ \s ){4} (\d+)/xms;?
But I have to put output to variable to compare with disk limit.
Something I don't understand


Laurent_R
Veteran / Moderator

Mar 30, 2017, 8:00 AM


Views: 7433
Re: [digioleg54] How correctly split complicated string

Hi,

Try to replace this:

Code
$_ = $dsk_used; 
print m/^ ^ (?: [^\s]+ \s ){4} (\d+)/xms;


with this:

Code
my $used = $1 if $disk_used =~  m/^(\S+ \s+ ){4} (\d+)/xms; 
print "$used\n";


The idea is that whatever is matched by (\d+) will be captured into $1 and assigned to $used.


BillKSmith
Veteran

Mar 30, 2017, 8:08 AM


Views: 7431
Re: [digioleg54] How correctly split complicated string

Does my example work exactly as it is posted? I do not see how yours is different, but you did not post a complete example which demonstrates the failure.


As far as storing the result in a variable, you are very close.

Code
($_) = m/^ ^ (?: [^\s]+ \s ){4} (\d+)/xms;


The match returns the value (or undef if match fails) only if it is in list context.

Lets examine the Regex. The /x tells regex compiler to ignore spaces. This allows me to make it easier to read by spreading it out. The /m changes the definition of the anchor '^' from 'start of string' to 'start of line'. The /s is not really needed in this case. Therefore the '^ ^' mean 'start the match at the start of the second line'. It looks for exactly four fields each of which consists of a string of non-whitespace characters followed by exactly one whitespace character. This code uses 'non-capturing parenthesis' (?: ... ) because we do not want to return these fields. The fifth field is surrounded by 'capturing parenthesis' because it is the result we want captured and returned. It consists of the longest possible string of decimal digits (\d+).
Good Luck,
Bill


FishMonger
Veteran / Moderator

Mar 30, 2017, 8:28 AM


Views: 7428
Re: [digioleg54] How correctly split complicated string

Here's an option using the split function.


Code
use warnings; 
use strict;

my $dsk_used = (`df -k . | grep -v -i CAPACITY`)[1];
my $used_space = (split ' ', $dsk_used)[4];

print $used_space;



(This post was edited by FishMonger on Mar 30, 2017, 8:28 AM)


digioleg54
User

Mar 30, 2017, 9:58 AM


Views: 7425
Re: [FishMonger] How correctly split complicated string

Bill, Laurent

Your examples gives me:


USED SPACE Filesystem 1024-blocks Free %Used

Use of uninitialized value in pattern match (m//) at ./oleg.pl line 51.
Use of uninitialized value in concatenation (.) or string at ./oleg.pl line 52.

The last works, if I put it into an array:


my @dsk_used=`df -k . | grep -v -i CAPACITY`;

my $used_space = (split ' ', $dsk_used[1])[4];

print $used_space;

output
114311

Thanks a lot all for help


FishMonger
Veteran / Moderator

Mar 30, 2017, 10:03 AM


Views: 7422
Re: [digioleg54] How correctly split complicated string

You don't need the array if you do a slice to grab the 2nd element; which is what my example did.


digioleg54
User

Mar 30, 2017, 10:27 AM


Views: 7420
Re: [FishMonger] How correctly split complicated string

you are right, as usually. Didn't check carefully

Thanks