Sorting output based on row value with Linux bash

39 views Asked by At

I need to print the whole output sorted based on 'Resident Set Size' value.

Process: wccpd
Memory (bytes)
Total Virtual Size 29.5
Resident Set Size 4.0

Process: writeback
Memory (bytes)
Total Virtual Size 0
Resident Set Size 0

Process: zxfrd
Memory (bytes)
Total Virtual Size 71.3
Resident Set Size 3.9

1

There are 1 answers

0
William Pursell On

perl is pretty good at this sort of thing:

#!/usr/bin/env perl

use 5.12.0;
$/ = "";  # enable "paragraph mode"

my @f;
while(<DATA>) {
    m/Resident Set Size (.*)/;
    push @f, [$1, $_];
}
say $_->[1] foreach sort { $a->[0] <=> $b->[0] } @f;


__DATA__
Process: wccpd
Memory (bytes)
Total Virtual Size 29.5
Resident Set Size 4.0

Process: writeback
Memory (bytes)
Total Virtual Size 0
Resident Set Size 0

Process: zxfrd
Memory (bytes)
Total Virtual Size 71.3
Resident Set Size 3.9

The idea is pretty simple. Setting $/ (aka $INPUT_RECORD_SEPARATOR or $RS) to the empty string puts perl in "paragraph mode" where records are separated by blank lines. We then read the file one record at a time and parse each record to match "Resident Set Size" and find the value on which you wish to sort. We then push an array reference consisting of the value in [0] and the whole record in [1]. Then you use the <=> operator to compare the records in the sort function.

If you have your input in the file input and want to execute something like this directly, you can do:

perl -00 -nE 'm/Resident Set Size (.*)/; push @f, [$1, $_]}
    { say $_->[1] foreach sort { $a->[0] <=> $b->[0] } @f' input

This is precisely the same as the above script, where the -n performs the while(<>) loop and -00 enables paragraph mode. The oddly mismatchted } { are a perl idiom for use with -n. The -n flag basically puts a while(<>){ } loop around the entire script, and we are closing that loop with the first } and matching its closing brace with the (seemingly unmatched) {.