2

Given inputfile

Cherries:20:100:300
Beans:12:400:500
Tomatoes:32:445:234
Potatoes:24:400:200
Kiwis:23:230:435

I have an awk script, named testscript.script:

BEGIN{ FS = ":" 
print "------------------------"
}

if($3 + $4 > 500) {print $1, $2}
END{
print "------------------------" 
}

The output of this script when invoked with awk -f testscript.script inputfile is as follows:

------------------------
Beans 12
Tomatoes 32
Potatoes 24
Kiwis 23
------------------------

I want to sort this list alphabetically (by name), then store it to a variable so that this list is printable in the end block of the awk script.

I.e. the code should look something like this.

BEGIN{ FS = ":" 
print "------------------------"
}

*if($3 + $4 > 500) {print $1, $2 | "sort" = variable}
END{
print "------------------------" 
print variable
}

And the print variable command would yield

------------
------------
Beans 12
Kiwis 23
Potatoes 24
Tomatoes 32

With the sorted list of items as the variable, and printing it in the END block after the dotted line.

What is the best way to do this?

7
  • can you give the input file contents.
    – Kamaraj
    Nov 2, 2016 at 2:25
  • @Kamaraj edited.
    – Anonymous
    Nov 2, 2016 at 2:28
  • What flavor of awk? Does it have an asorti function? Nov 2, 2016 at 2:39
  • 1
    Since the sort command can't terminate until it receives an end-of-file, and you never close it, this seems a bit silly. Why not just add a shell wrapper script to pipe the output of the Awk script through sort?
    – Wildcard
    Nov 2, 2016 at 4:14
  • 1
    @KMoy, this is relevant. I'm having trouble understanding why you would want the sorted list after both ------ lines and not before. Did I get that correctly that that's what you want?
    – Wildcard
    Nov 2, 2016 at 4:59

3 Answers 3

2
echo "---------------";awk -F: '$3+$4>500{print $1,$2}' inputfile |sort && echo "---------------"

using awk

awk -F: '$3+$4>500{Arr[$1]=$2}END{n=asorti(Arr,SArr);for(i=1;i<=n;i++){print SArr[i],Arr[SArr[i]]}}' inputfile
3
  • Asorti is not built-in on my interpreter.
    – Anonymous
    Nov 2, 2016 at 3:57
  • you want to achieve this using awk and store sorted values in variable in awk and print in END section ?
    – Kamaraj
    Nov 2, 2016 at 4:13
  • That is correct.
    – Anonymous
    Nov 2, 2016 at 4:28
0

When considering the 'Best' way there is a lot that goes in, I think of best as fastest route meeting my needs. If you are trying to pass a variable beyond the scope of your process I would suggest piping it out to a ram-drive, almost all distros have one, then process your test, and pipe out from that ramdisk after you are done.

On Debian based distros you'll find a ram drive is located at /run/shm, so something like this might meet you needs.

cat inputdata.file | sed 's/:/ /g' | awk '{print $1" "$2}' | sort -k 1,1 > /run/shm/datastore.file; echo '------------------------' > datastore2.file; cat /run/shm/datastore.file>>/run/shm/datastore2.file; cat /run/shm/datastore2.file>~/destination.file

When the way a process wants to do something is limiting you, just control the formatting with logic and a ramdrive. Dont forget to move your data after processing as anything in /run/shm/* is toast once you reboot. I hope this helps. Ill keep an eye in case i misunderstood what you need.

0

You can stick the whole thing into a shell script and pipe the Awk output to sort before it gets printed.

Assuming you want the lines above and below the sorted output (which makes more sense to me visually):

#!/bin/sh
printf '%s\n' ------------------------
cat "$@" | awk -F: '($3 + $4 > 500) {print $1, $2}' | sort
printf '%s\n' ------------------------

With this saved in a file called myscript set to executable, and running on the inputfile you specified by calling:

./myscript inputfile

The output looks like:

------------------------
Beans 12
Kiwis 23
Potatoes 24
Tomatoes 32
------------------------

Note the use of "$@" so that this script can handle multiple file arguments, not just one, just the way Awk can do.

You could also skip using cat and just do:

awk -F: '($3 + $4 > 500) {print $1, $2}' "$@" | sort

However, I personally don't like passing filenames in places where they could be interpreted as code. So I would use cat to concatenate the files.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .