awkslurm

Getting the total count of IDs from a comma delimited list of IDs that can contain ranges with awk


I'm trying to get the total count of CPUs allocated to a job from SLURM's scontrol --details --oneliner show job output. The format is a comma delimited list of CPU IDs that can contain hyphen-delimited ranges.

Here's an extract of my code, which doesn't work (I get 40 instead of 22):

echo 0,2-11,48-58 |

awk '
    {
        cpus = 0;
        m = split($0, arr, ",");
        for (j = 1; j <= m; j++)
            cpus += ( idx = index(arr[j], "-") \
                 ? 1 + substr(arr[j], idx+1) - substr(arr[j], 1, idx-1) \
                 : 1 \
            );
        print cpus
    }
'
40

What's happening ? I'm using GNU Awk 4.2.1, API: 2.0 (GNU MPFR 3.1.6-p2, GNU MP 6.1.2)


Solution

  • Instead of the intended:

    ( idx = index(arr[j], "-")) ? … : 1; # compute idx, then if it is > 0 do …
    

    your parenthesis are:

    ( idx = index(arr[j], "-") ? … : 1);
    

    which is equivalent to:

    idx = (index(arr[j], "-") ? … : 1); # set idx to "if index() > 0 …"
    

    Thus when using idx in the it is not defined yet (thus 0),
    or, on the later iterations, equal to the integer extracted on the previous iteration.

    Your full script with parenthesis at the right place:

    echo 0,2-11,48-58 |
    
    awk '
        {
            cpus = 0;
            m = split($0, arr, ",");
            for (j = 1; j <= m; j++)
                cpus += ( idx = index(arr[j], "-")) \
                     ? 1 + substr(arr[j], idx+1) - substr(arr[j], 1, idx-1) \
                     : 1 \
                ;
            print cpus
        }
    '
    

    (… I understood the problem while adding an idx = …; print …; to diagnose before your ? :, and was surprised to get the intended 22)