From owner-freebsd-chat Fri Jan 17 1:40:15 2003 Delivered-To: freebsd-chat@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4AE9F37B401; Fri, 17 Jan 2003 01:40:13 -0800 (PST) Received: from dreadnought.cnchost.com (dreadnought.cnchost.com [207.155.248.18]) by mx1.FreeBSD.org (Postfix) with ESMTP id E80DC43EB2; Fri, 17 Jan 2003 01:40:12 -0800 (PST) (envelope-from bakul@bitblocks.com) Received: from bitblocks.com (adsl-209-204-185-216.sonic.net [209.204.185.216]) by dreadnought.cnchost.com id EAA14712; Fri, 17 Jan 2003 04:40:12 -0500 (EST) [ConcentricHost SMTP Relay 1.15] Message-ID: <200301170940.EAA14712@dreadnought.cnchost.com> To: "Crist J. Clark" Cc: freebsd-chat@FreeBSD.ORG Subject: Re: Script Challenge In-reply-to: Your message of "Thu, 16 Jan 2003 21:44:59 PST." <20030117054458.GA50247@blossom.cjclark.org> Date: Fri, 17 Jan 2003 01:40:11 -0800 From: Bakul Shah Sender: owner-freebsd-chat@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org > Items in the database can contain sub-items which in turn contain > sub-items with no hard limit to the recursion. ... > I want to sort each level. ... > Like I said, I used a Perl script with a recursive function to do > it, but it ain't all that pretty. I suspect I'm missing a really cool > way to do it. Any suggestions? (Any language will do.) Attached below is a small scheme script (using Aubrey Jaffer's scm and slib -- see /usr/ports/lang/scm). When it is fed your sample input :b_item (value) :a_item ( :z_subitem(value) :x_subitem(value) :y_subitem( :r_subsubitem(value) :t_subsubitem(vaule) :s_subsubitem(value) ) :w_subitem(value) ) :c_item(value) It produces ((:a_item (:w_subitem value) (:x_subitem value) (:y_subitem (:r_subsubitem value) (:s_subsubitem value) (:t_subsubitem vaule)) (:z_subitem value)) (:b_item value) (:c_item value)) As you can see the output is formatted as one big list. Such "lispy" formats are trivial to read in and easy to process. But if you don't like that, you can write a simple converter back to your format or convert this script to linenoise perl. Note: the input can have any amount of whitespace and there is virtually no limit on nesting. But the script does assume Scheme input syntax. If not, you have to replace (read) with your own. It also assumes all lists have either 1 item or an even number of items (i.e. no errors). -- bakul cat > sortdb.scm <string (car a)) (symbol->string (car b)))) (define (sort-value l) (if (or (null? l) (null? (cdr l))) l (sort-list l '()))) (define (sort-list l result) (if (null? l) (sort result less?) (sort-list (cddr l) (cons (cons (car l) (sort-value (cadr l))) result)))) (define (read-db p) (let loop ((result '()) (item (read p))) (if (eof-object? item) (sort-value (reverse result)) (loop (cons item result) (read p))))) (pretty-print (read-db (current-input-port))) EOF chmod +x sortdb.scm sortdb.scm < tst-db > sorted-tst-db To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-chat" in the body of the message