Sort file lines based on a template in bash

I have a file containing the following lines:

This test took 1201ms to execute
The IO operation cost 113ms
Main thread have been executing for 16347ms

How can I sort them by the number next to ms?

I used the following command sedbut did not work

sed -r 's/[[:digit]]\+ms//g' file.txt | sort -r | > tmp
+4
source share
4 answers
$ awk '{match($0,/[[:digit:]]+ms/,a)}{print substr(a[0], 1, length(a[0])-2),$0}' inputFile | sort -nk1 | cut -f2- -d ' '
The IO operation cost 113ms
This test took 1201ms to execute
Main thread have been executing for 16347ms

awkmatches [[:digit:]]msand prints it (except for the last two characters ms) at the beginning of the line and sortusing the first field. cutlater deletes the first field and returns the original string.

+2
source

GNU awk:

awk 'BEGIN {PROCINFO["sorted_in"]="@ind_num_asc"} \
        {idx=gensub(".*\\s+([0-9]+).*", "\\1", "g"); arr[idx]=$0} \
          END{for (i in arr) print arr[i]}' file.txt
  • PROCINFO["sorted_in"]="@ind_num_asc" variable sets (associative) array sort order based on numeric index

  • {idx=gensub(".*\\s+([0-9]+).*", "\\1", "g"); arr[idx]=$0} arr ,

  • END{for (i in arr) print arr[i]}

, :

PROCINFO["sorted_in"]="@ind_num_desc"

:

% cat file.txt
This test took 1201ms to execute
The IO operation cost 113ms
Main thread have been executing for 16347ms

% awk 'BEGIN {PROCINFO["sorted_in"]="@ind_num_asc"} {idx=gensub(".*\\s+([0-9]+).*", "\\1", "g"); arr[idx]=$0} END{for (i in arr) print arr[i]}' file.txt
The IO operation cost 113ms
This test took 1201ms to execute
Main thread have been executing for 16347ms
+2

GNU awk (gawk):

$ awk 'BEGIN{PROCINFO["sorted_in"]="@val_num_asc"} {for (i=1;i<=NF;i++) if ($i~/ms$/){a[$0]=$i+0; break}} END{for (line in a)print line}' file.txt
The IO operation cost 113ms
This test took 1201ms to execute
Main thread have been executing for 16347ms

  • BEGIN{PROCINFO["sorted_in"]="@val_num_asc"}

    awk . GNU.

  • for (i=1;i<=NF;i++) if ($i~/ms$/){a[$0]=$i+0; break}

    , ms. , a , .

  • END{for (line in a)print line}

    , , a. a , .

+1

You can use sedto extract the numerical part and place it at the beginning of the line with a separator, and then sortalong the first field and use cutto remove the added field:

sed -E 's/^(.*) ([[:digit:]]+)ms(.*)$/\2|\1 \2ms\3/' file | # extract ms and place it at the beginning
  sort -t '|' -k1,1n |                                      # sort it by the field added above
  cut -f2- -d '|'                                           # remove the field

Conclusion:

The IO operation cost 113ms
This test took 1201ms  to execute
Main thread have been executing for 16347ms
+1
source

Source: https://habr.com/ru/post/1693848/


All Articles