Sort String using awk


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Sort String using awk
# 1  
Old 03-11-2014
Sort String using awk

Hi,
I need help to sort string using awk. I don't want to use sed or perl as I want to add this functionality in my existing awk script
Basically I have a variable in AWK which is string with comma separated value. I want to sort that string before using that variable in further processing
for e.g.
Code:
echo  " PQR, ABCddf, LMNS, AAAB "|awk '{ gsub(/[[:blank:]]+/,""); SORTME=$0 ; print SORTME}'

Current output is
Code:
PQR,ABCddf,LMNS,AAAB

I want output to be sorted by words in string which are comma separated. I would like output to be displayed as
Code:
AAAB,ABCddf,LMNS,PQR

Can someone please help me to sort the output in alphabetical order

Last edited by rocky.community; 03-11-2014 at 06:25 PM.. Reason: Removed spaces
# 2  
Old 03-11-2014
Try (using a bubble sort algorithm):
Code:
echo  " PQR, ABCddf, LMNS, AAAB "|
awk '
  {
    do {
      c="";
      for(i=1;i<NF;i++){
        if($i>$(i+1)){
          c=$i; $i=$(i+1); $(i+1)=c
        }
      }
    }
    while(c!="")
  }
  1
' FS=, OFS=,

or using GNU awk:
Code:
gawk '
  {
     n=split($0,F)
     asort(F)
     for(i=1; i<=n; i++) $i=F[i]
  }
  1
' FS=, OFS=,

It happens to go right with the spaces that are being used, but be either careful to leave out spaces or add some code to remove the spaces...

Last edited by Scrutinizer; 03-12-2014 at 08:00 PM.. Reason: optimization
# 3  
Old 03-11-2014
Code:
echo  " PQR, ABCddf, LMNS, AAAB" |
awk -F, '{
    for (k=1; k<=NF; k++) x[k]=$k

    for (i=1; i<NF; i++)
        for (j=1; j<(NF+1-i); j++)
            if (x[j] > x[j+1]) {t = x[j]; x[j] = x[j+1]; x[j+1] = t}

    for (i=1; i<=NF; i++) printf("%s", (i < NF ? (i > 1 ? x[i] FS : "\"" x[i] FS) : x[i] "\"" RS))
}'

# 4  
Old 03-12-2014
With gnu awk you can also use PROCINFO["sorted_in"] like this:

Code:
echo  " PQR, ABCddf, LMNS, AAAB " | awk '
{
  PROCINFO["sorted_in"] = "@val_str_asc"
  split($0,cmds,"[ ,]*") 
  for (val in cmds) printf "%s",(k++>2?",":"") cmds[val]
  printf "\n"
}'


Last edited by Chubler_XL; 03-12-2014 at 12:25 AM.. Reason: borken code tags
# 5  
Old 03-12-2014
[ Solved ] Sort String using awk

Excellent!!
Thanks for your help. I don't have GNU awk so all other solutions works good for me.

Last suggestion given by Chubler_XL does not give right output but rest all works good.
Thanks for your support.

---------- Post updated at 02:00 PM ---------- Previous update was at 09:52 AM ----------

Hi,

Sorry to come back again on same issue.I am stuck again with solution
I am trying to use solution provided by shamrock
How do I put that part in function so that whatever string I pass, it will sort and give me output in variable for further usage like comparison as below
Code:
snamelist="AAAB,ABCddf,LMNS,PQR:VALUE1 AAB,ABSSf,LMNS,DFD:VALUE2 LMNS,ABCddf,PQR,AAAB:VALUE3"
for sname in $snamelist
do
    BASELINE="AAAB,ABCddf,LMNS,PQR"
    echo  "$sname" | awk -v baseline="$BASELINE" 'BEGIN { FS=":" }
    { pref=$1 ; if (pref == baseline) { svcstatus = "OK" } else { svcstatus = "NOT-OK" }  ;
    printf "%-35s %-35s %-35s %-10s\n", sname, pref, baseline, svcstatus}'
done

In my actual program, pref and baseline will not be shell variable but variable in awk itself derived based on line of input. So before comparing (pref == baseline), I want to sort both so that compare can work. something like below where sortme will be function defined inline using code provided by shamrock.
looking something as below
Code:
snamelist="AAAB,ABCddf,LMNS,PQR:VALUE1 AAB,ABSSf,LMNS,DFD:VALUE2 LMNS,ABCddf,PQR,AAAB:VALUE3"
for sname in $snamelist
do
    BASELINE="AAAB,ABCddf,LMNS,PQR"
    echo  "$sname" | awk -v baseline="$BASELINE" 'BEGIN { FS=":" }
{<DEFINE SORTME FUNCTION HERE>}
    { pref=$1 ; if (sortme(pref) == sortme(baseline)) { svcstatus = "OK" } else { svcstatus = "NOT-OK" }  ;
    printf "%-35s %-35s %-35s %-10s\n", sname, pref, baseline, svcstatus}'
done

Appreciate your help.
# 6  
Old 03-12-2014
@OP:

To sort any input string you'd have to factor out the sort part and put it into file as a standalone function and only then you can do what you are trying to get at...so put the sort function and the awk statements into a file called "sortme"...

$ cat sortme
Code:
function sortme(x,f,    j, k)
{
    for (j=1;j<f;j++)
        for (k=1;k<=f-j;k++)
            if (x[k] > x[k+1]) {
                t=x[k]
                x[k]=x[k+1]
                x[k+1]=t
            }
}

BEGIN {FS = ":" }

{
    pref=$1
    m = split(pref, srt_pref, ",")
    n = split(baseline, srt_baseline, ",")
    if (sortme(srt_pref, m) == sortme(srt_baseline, n)) svcstatus = "OK"
    else svcstatus = "NOT-OK"
    printf "%s %s %s %s\n", sname, pref, baseline, svcstatus
}

After creating the "sortme" file...change the statements inside your script...
Code:
snamelist="AAAB,ABCddf,LMNS,PQR:VALUE1 AAB,ABSSf,LMNS,DFD:VALUE2 LMNS,ABCddf,PQR,AAAB:VALUE3"

for sname in $snamelist
do
    BASELINE="AAAB,ABCddf,LMNS,PQR"
    echo  "$sname" | awk -v baseline="$BASELINE" -f sortme
done

# 7  
Old 03-12-2014
Bubble sort an array inside the function, which calls an array by reference, so the arrays are sorted afterwards. Then compare arrays outside the function.
Code:
snamelist="AAAB,ABCddf,LMNS,PQR:VALUE1 AAB,ABSSf,LMNS,DFD:VALUE2 LMNS,ABCddf,PQR,AAAB:VALUE3"
BASELINE="AAAB,ABCddf,LMNS,PQR"

printf "%s\n" $snamelist | 
awk -F: -v baseline="$BASELINE" '
  function arrsort(A,	n,i,c){
    n=length(A)
    do {
      c=""; 
      for(i=1;i<n;i++) {
        if(A[i]>A[i+1]) {
          c=A[i]; A[i]=A[i+1]; A[i+1]=c
        }
      }
    }
    while(c!="")
  }

  BEGIN{
    split(baseline,B,/,/)
    arrsort(B)
  }

  {
    split($1,F,/,/)
    arrsort(F)
    svcstatus="OK"
    for(i in F) if(B[i]!=F[i]) svcstatus="NOT-OK"
    printf "%s %s %s %s\n", $0, $1, baseline, svcstatus
  }
'

This is using a sorting method, but since the only goal is to find out if all values are present in both strings, it seems to me that this could also be done without sorting...



--
@shamrock: if (sortme(srt_pref, m) == sortme(srt_baseline, n)) is always true, no? Since the output of the sortme function is always an empty string..

Last edited by Scrutinizer; 03-12-2014 at 09:20 PM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Sort only numbers within a string

Hi, I am having contents in a file like below, cat testfile rpool/swap rpool/swap14 rpool/swap2 rpool/swap3 I want to sort the above contents like, rpool/swap rpool/swap2 rpool/swap3 rpool/swap14 I have tried in this way, (7 Replies)
Discussion started by: Sumanthsv
7 Replies

2. Shell Programming and Scripting

how to sort lines in the string

Hi guys, I am trying to sort numbers in the string in descending order but for some reason sort fails. n129$ echo "81 240" | sort -r 81 240 n129$ I am not sure what am I doing wrong. Is there a 100% reliable way to make sure that sort will always work. I mean on SUNS and IBM machines. ... (4 Replies)
Discussion started by: aoussenko
4 Replies

3. Shell Programming and Scripting

Remove duplicate chars and sort string [SED]

Hi, INPUT: DCBADD OUTPUT: ABCD The SED script should alphabetically sort the chars in the string and remove the duplicate chars. (5 Replies)
Discussion started by: jds93
5 Replies

4. Shell Programming and Scripting

sed or awk command to replace a string pattern with another string based on position of this string

here is what i want to achieve... consider a file contains below contents. the file size is large about 60mb cat dump.sql INSERT INTO `table1` (`id`, `action`, `date`, `descrip`, `lastModified`) VALUES (1,'Change','2011-05-05 00:00:00','Account Updated','2012-02-10... (10 Replies)
Discussion started by: vivek d r
10 Replies

5. UNIX for Dummies Questions & Answers

List directories with given string, sort by creation date

It is for HP-Unix B.11.31. Requirement: 1. List the directories, which directories name has given particular string. Example: Directories with name "Build" 2. On the output of 1. list the directories by creation date as sort order. I tried with; find . -type d -name "Build*" ... (3 Replies)
Discussion started by: Siva SQL
3 Replies

6. Shell Programming and Scripting

awk: sort lines by count of a character or string in a line

I want to sort lines by how many times a string occurs in each line (the most times first). I know how to do this in two passes (add a count field in the first pass then sort on it in the second pass). However, can it be done more optimally with a single AWK command? My AWK has improved... (11 Replies)
Discussion started by: Michael Stora
11 Replies

7. Shell Programming and Scripting

Require help to sort string

Hi Folks, Currently am working with 10g db. I want to sort the below o/p. Current output: ============ SQL> select partition_name from user_tab_partitions where table_name='USER_AUDIT'; PARTITION_NAME ------------------------------ PARTMAX PART_AUDIT_NOV02 PART_AUDIT_NOV08... (4 Replies)
Discussion started by: sathik
4 Replies

8. Shell Programming and Scripting

Sort based on string lenght.

I'm not familiar with find. If i use find in a certain directory i want it to show based on hierarchy. find . type d fol1 fol1/subfol1 fol1/subfol1/subfol1 fol2 fol2/subfol2 i want it to show like this fol1/subfol1/subfol1 fol1/subfol1 fol1 fol2/subfol2 fol2 do i need to use... (5 Replies)
Discussion started by: ryandegreat25
5 Replies

9. Shell Programming and Scripting

sort entire line based on part of the string

hey gurus, my-build1-abc my-build10-abc my-build2-abc my-build22-abc my-build3-abc basically i want to numerically sort the entire lines based on the build number. I dont zero pad the numbers because thats "how it is" ;-) sort -n won't work because it starts from the beginning. ... (10 Replies)
Discussion started by: gurpal2000
10 Replies

10. Shell Programming and Scripting

How to sort a string with numbers

Hi, I need help to sort a file contents. I am using sort -r option to basically reverse the comparison in descending order. However, i found out that my file is not sorted according, can anyone please help. My data is something like:- Hello world 20.982342864 343 19.234355545 222... (5 Replies)
Discussion started by: ahjiefreak
5 Replies
Login or Register to Ask a Question