t-rex has asked for the wisdom of the Perl Monks concerning the following question:

Hi guys, in this forum after a long time. I have this file which gives me info like below :

available: 8 nodes (0,8,250-255) node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 2 +2 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 4 +5 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 6 +8 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 node 0 size: 129733 MB node 0 free: 125997 MB node 8 cpus: 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 1 +05 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 12 +2 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 + 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 +157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 1 +74 175 node 8 size: 129826 MB node 8 free: 126395 MB node 250 cpus: node 250 size: 16128 MB node 250 free: 16127 MB node 251 cpus: node 251 size: 12032 MB node 251 free: 12031 MB node 252 cpus: node 252 size: 16128 MB node 252 free: 16127 MB node 253 cpus:

i want to extract the node number where there is nothing after the cpu colon (cpus:), example this line

node 252 cpus:

since there is nothing after the "cpus:" , i want to extract 252 from this line. I have to do this for entire file.

I wrote a regex but is not working getting me the output, pls help

here is what i wrote :

my $str = "node 250 cpus:"; #my ($a) = $str =~ /:\s*(.+)$/; if(($str =~ /:\s*(.+)$/) eq ""){ #extract node }

2019-01-30 Athanasius added closing code tag

Replies are listed 'Best First'.
Re: extracting value in a string after checking value after colon ':'
by Athanasius (Archbishop) on Jan 30, 2019 at 06:51 UTC

    Hello t-rex and welcome back!

    To match a line in which nothing follows the colon (other than the terminal newline, of course), simply match on :$:

    use strict; use warnings; while (<DATA>) { print "$1\n" if / ^ node \s+ (\d+) \s+ \w+ : $ /x; } __DATA__ available: 8 nodes (0,8,250-255) node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 2 +2 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 4 +5 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 6 +8 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 node 0 size: 129733 MB node 0 free: 125997 MB node 8 cpus: 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 1 +05 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 12 +2 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 + 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 +157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 1 +74 175 node 8 size: 129826 MB node 8 free: 126395 MB node 250 cpus: node 250 size: 16128 MB node 250 free: 16127 MB node 251 cpus: node 251 size: 12032 MB node 251 free: 12031 MB node 252 cpus: node 252 size: 16128 MB node 252 free: 16127 MB node 253 cpus:

    Output:

    16:43 >perl 1971_SoPW.pl 250 251 252 253 16:44 >

    But if whitespace is allowed after the colon, change to:

    while (<DATA>) { print "$1\n" if / ^ node \s+ (\d+) \s+ \w+ : \s* $ /x; # ^^^ }

    Update: Removed unnecessary chomp from the first code block.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Thanks

      but this is not working, i get error like

      Use of uninitialized value $_ in pattern match (m//) at gpu.pl line 8

        You will not get that if you run the code as written, so you have changed something. Post the full code you are running as an SSCCE if you would like assistance to debug further.

        Please show the code that gave you this Use of uninitialized value $_ warnings. It would not happen with the code as written by Athanasius , so you must have done something differently.

        secondly if you see the file, there are many lines, i only want to extract the node number (250,251..) only if string cpus: is empty after the colon.

        Hope i made my question clear

Re: extracting value in a string after checking value after colon ':'
by johngg (Canon) on Jan 30, 2019 at 17:00 UTC

    You could use a negative look-ahead, i.e. only print the number from the "cpus:" line if the colon is not followed by more space-separated digits.

    johngg@shiraz:~/perl/Monks$ perl -Mstrict -Mwarnings -E ' open my $inFH, q{<}, \ <<__EOD__ or die $!; available: 8 nodes (0,8,250-255) node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 2 +2 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 4 +5 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 6 +8 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 node 0 size: 129733 MB node 0 free: 125997 MB node 8 cpus: 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 1 +05 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 12 +2 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 + 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 +157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 1 +74 175 node 8 size: 129826 MB node 8 free: 126395 MB node 250 cpus: node 250 size: 16128 MB node 250 free: 16127 MB node 251 cpus: node 251 size: 12032 MB node 251 free: 12031 MB node 252 cpus: node 252 size: 16128 MB node 252 free: 16127 MB node 253 cpus: __EOD__ while ( <$inFH> ) { say $1 if m{(?x) ( \d+ ) \s+ cpus: (?! \s* \d) }; } close $inFH or die $!;' 250 251 252 253

    I hope this is helpful.

    Cheers,

    JohnGG

Re: extracting value in a string after checking value after colon ':'
by thanos1983 (Parson) on Jan 30, 2019 at 09:58 UTC

    Hello t-rex,

    Welcome back to the Monastery :)

    Fellow Monks have provided you with solution(s). Just for fun a way to load multiple files:

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my %hash; my @array; while (<>) { chomp; next unless /^node*/; # skip lines that do not start with string +node my @tmp = split / /; push @array, $tmp[1]; } continue { close ARGV if eof; $hash{$ARGV} = [ @array ]; } print Dumper \%hash; __END__ $ perl test.pl in.txt in2.txt $VAR1 = { 'in2.txt' => [ '0', '0', '0', '8', '8', '8', '250', '250', '250', '251', '251', '251', '252', '252', '252', '253', '0', '0', '0', '8', '8', '8', '250', '250', '250', '251', '251', '251', '252', '252', '252', '253' ], 'in.txt' => [ '0', '0', '0', '8', '8', '8', '250', '250', '250', '251', '251', '251', '252', '252', '252', '253' ] };

    Hope this helps, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!
Re: extracting value in a string after checking value after colon ':'
by shadowsong (Pilgrim) on Jan 31, 2019 at 00:13 UTC

    Hi t-rex

    While there’s not much more value to be added beyond Athanasius’ response; (assuming your data resides in "file.txt") here's the obligatory one-liner:

    perl -lwne "print $1 if /(\d+)\s+cpus:\s*$/" file.txt

    Best of luck
    Shadowsong