2

I want to read out some files and sort the output.

For example:

cat example.conf Order: 0 Package: example cat another.conf Order: 2 Package: another cat file.conf Order: 1 Package: file 

I output them with: awk '/Order|Package/' conf/*.conf:

Order: 2 Package: another Order: 0 Package: example Order: 1 Package: file 

I would like the output to be sorted by the number after Order: but without breaking the relation between the lines like:

Order: 0 Package: example Order: 1 Package: file Order: 2 Package: another 

5 Answers 5

4

If you have GNU awk > 4.0, and assuming the Order record always precedes the Package record, then

gawk '/^Order/ {order = $2} /^Package/ {p[order] = $0} END { PROCINFO["sorted_in"] = "@ind_num_asc" for (i in p) {print "Order:", i; print p[i]} } ' conf/*.conf Order: 0 Package: example Order: 1 Package: file Order: 2 Package: another 

For older gawk you can use asorti:

gawk '/^Order/ {order = $2} /^Package/ {p[order] = $0} END { n = asorti(p,b) for (i=1;i<=n;i++) {print "Order:", i; print p[b[i]]} } ' conf/*.conf 
0
0

Works for files, which contains two lines, only.

sed -n 'N; s/\n//p' *.conf | sort | sed -n 's/\(Package\)/\n\1/p'

Explanation:

  1. sed -n 'N; s/\n//p' *.conf - removes newline between two lines, that is, it joins two contiguous lines in to the one.
  2. sort - sorts long lines, which was made in the previous step.
  3. sed -n 's/\(Package\)/\n\1/p' - returns newline back to its place.

Output:

Order: 0 Package: example Order: 1 Package: file Order: 2 Package: another 
0

A naive Unix aproach:

awk '/Order|Package/' conf/*.conf | # get your usual output paste - - | # convert two lines to one sort -n -k2,2 | # sort numerically awk '{print $1,$2;print $3,$4}' # re-print in two columns 
0

Python script

#!/usr/bin/env python from __future__ import print_function import sys def get_order_package(filename): order=None package=None with open(filename) as f: for line in f: if line.startswith('Order:'): order=int(line.strip().split()[1]) if line.startswith('Package:'): package=line.strip().replace("Package: ",'') return (order,package) order_list=[] for argument in sys.argv[1:]: order_list.append(get_order_package(argument)) order_list.sort(key=lambda x: x[0]) for i in order_list: print('Order:',i[0]) print('Package:',i[1]) 

This script defines get_order_package() function which parses the file, and returns tuple in format (integer,package_string). We pass all files as command-line arguments and iterate over them, executing the function explained above for each one. That builds up a list, we sort it, and iterate again, printing each respective tuple parts from the new sorted list.

Test run

$ cat example_1.conf Order: 0 Package: example_1 $ cat example_2.conf Order: 2 Package: example_2 $ cat example_3.conf Order: 1 Package: example_3 $ ./parse_conf.py *.conf Order: 0 Package: example_1 Order: 1 Package: example_3 Order: 2 Package: example_2 
0

This works too:

grep -e ^Order -e ^Package `grep ^Order *.conf | awk -F: '{printf("%s:%s\n",$NF,$0);}' |sort| awk -F: '{print $2}'` 

Explanation (below multi-line format is only for demonstration, it does not work in bash because the resultant single-line command cannot handle the comments):

$ grep -e ^Order -e ^Package ` \ # grep for lines starting with "Order" or "Package"; start nested command > grep ^Order *.conf | \ # grep for lines starting with "Order" in files *.conf > awk -F: '{printf("%s:%s\n",$NF,$0);}' | \ # prefixing order number with a separating colon > sort | \ # sort by order number > awk -F: '{print $2}' \ # extract file name alone ; now filenames are ordered by the order number contained within them > ` # end nested command 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.