0

I am very new to awk and I am trying to sort the fifth group of my usernames which has " Zack e" in alphabetical order. I typed getent passwd in my terminal, which are:

zack:x:115:120:Zack E:/home/zack:/var/run/bin/bash/false
hp:x:118:7:HPLIP system user:/var/run/hplip:/bin/false
armvad:x:3:3:Ezikon Armvad:/dev:/usr/sbin/nologin
bruh:x:1542:1546:Burh RG:/home/banner:/bin/bash

I also tried this approached

for i in `sed -e 's/.* \(\d\)*/\1/' passwd.in | sort`; do grep $i passwd.in; done > file_sort.txt

But all it did was sort the first group instead of the desired group. How can I combine my approach with an awk script all I know to do in awk is BEGIN {FS = ":"} $5 == 1000{print $1}

Is there any way, I can rearrange the tokens so sort can work, and then put them back in order?

Newbie J
  • 186
  • 1
  • 19
Vlad Ezikon
  • 93
  • 2
  • 11
  • @tripleee None of the answers in the linked duplicate use awk for sorting. Then again, neither does the tried solution in the OP. – James Brown Mar 04 '19 at 07:52
  • 1
    Yeah, I'd go with "just use `sort`" but in any event, the questions are similar enough and the possible answers seem to just about cover it. Maybe add yours as an answer to that question and concur with the duplicate vote rather than have multiple distractingly similar questions with different answers. – tripleee Mar 04 '19 at 07:53

2 Answers2

1

Why 'awk' when 'sort' may do the job elegantly?

sort -t : -k5 myFile.txt

or, reversely

sort -r -t : -k5 myFile.txt
Frank-Rene Schäfer
  • 3,182
  • 27
  • 51
1

Using GNU awk and for scanning order for sorting at output when the $5 is unique for each record:

$ awk -F: '{a[$5]=$0}END{PROCINFO["sorted_in"]="@ind_str_asc";for(i in a)print a[i]}' file

Output:

bruh:x:1542:1546:Burh RG:/home/banner:/bin/bash
armvad:x:3:3:Ezikon Armvad:/dev:/usr/sbin/nologin
hp:x:118:7:HPLIP system user:/var/run/hplip:/bin/false
zack:x:115:120:Zack E:/home/zack:/var/run/bin/bash/false

Explained:

$ awk -F: '{                              # set field delimiter
     a[$5]=$0                             # hash records, use $5 as key
}
END {
    PROCINFO["sorted_in"]="@ind_str_asc"  # set the for traverse order
    for(i in a)                           # use it
        print a[i]                        # output
}' file

Since the hash key is $5 it needs to be unique to avoid collisions. If they are not unique, I guess in this case, where the records are unique, you could:

$ awk -F: '{
    a[$0]=$5                              # changed
}
END {
    PROCINFO["sorted_in"]="@val_str_asc"  # changed
    for(i in a)
        print i                           # changed
}' file

Then there are of course functions asort and asorti that sort arrays where as the above examples sorted at output. For example, we expect the $5 not to be unique:

$ awk -F: '{
    a[$0]=$5                      # record is unique, $5 is not expected to be
}
END {
    n=asorti(a,b,"@val_str_asc")  # asorti to preserve $0 in b but order from a[] value
    for(i=1;i<=n;i++)             # sorted to b, index rewritten from 1..n
        print i, b[i]
}' file

Output now:

1 bruh:x:1542:1546:Burh RG:/home/banner:/bin/bash
2 armvad:x:3:3:Ezikon Armvad:/dev:/usr/sbin/nologin
3 hp:x:118:7:HPLIP system user:/var/run/hplip:/bin/false
4 zack:x:115:120:Zack E:/home/zack:/var/run/bin/bash/false
James Brown
  • 36,089
  • 7
  • 43
  • 59