MACSCRPT Archives

November 2006

MACSCRPT@LISTSERV.DARTMOUTH.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Paul Berkowitz <[log in to unmask]>
Reply To:
Macintosh Scripting Systems <[log in to unmask]>
Date:
Fri, 17 Nov 2006 12:54:10 -0800
Content-Type:
text/plain
Parts/Attachments:
text/plain (75 lines)
Perhaps some of you can help out here, or direct me to somewhere I might
find an answer, which will probably be in the shell script area.

I'm looking for a fast (non-repeat loop) way of returning the index of a
list item given the item. (Yes, I have a very useful repeat loop for doing
this myself, but it's far too slow for the purposes for which I need it
here.) LNS's List & Record Tools osax has a great command 'difference' that
will get me (as list3) the items of a longer list2 that are not in a shorter
list1, but it can't get me the indices in list2 of these (list3) items.
(Akua back in OS 8 could do this.)

Once upon a time I was given an excellent perl script that could do the same
thing, absurdly fast, using perl's grep which can work with entire lists of
search items at once. Here it is. (It's in a form that can also be used to
look for an intersection of the lists rather than the difference between
them):


set list3 to my perlScript(list1, list2, "!")

on perlScript(list1, list2, bool) -- find which items of list1 are not in
list2 if bool = "!", which items of list 1 _are_ in list2 if bool = ""
     
    set lf to (ASCII character 10)
    
    set AppleScript's text item delimiters to {", "}
    set list1 to list1 as string
    set list2 to list2 as string
    set AppleScript's text item delimiters to {lf}
    set scpt to paragraphs of ("perl -e '
@list1 = (" & list1 & ");
@list2 = (" & list2 & ");

@check{@list2} = ();
@list3= grep " & bool & "exists $check{$_}, @list1;
print \"@list3\\n\";
'") as string
    
    set list3 to do shell script scpt
    
    set AppleScript's text item delimiters to {" "}
    set list3 to text items of list3
    set AppleScript's text item delimiters to {""}
    
    return list3
    
end perlScript



Now I was hoping to be able to use a variation of this to get the line
numbers (i.e. indices) within list2. Regular grep(1) has an -n option that
prefixes the line number to the line of found items. That would do fine. (Or
a method that returned just the indices.) But it doesn't work with perl's
grep.

Maybe there's a way to do it? Or a way to use regular grep -n in a some sort
of 'for' loop using each item of list1 in sequence? That sounds most likely
- how would I do that? (Regular grep seems to be a single-line command.) I
do not want to do this in an AppleScript repeat loop, but maybe some other
shell script can work on each line of the textified list1 (where each list
item is now its own line in a text string), piping each to grep -n? How
would I do that?

I also have a Python version of the same routine, using .split() in a 'for I
in list1' loop, which is [almost] quick enough I suppose, but once again I
don't know how to retrieve the index of the found item in list2 (I've
checked Python books to no avail) although I'd guess that's possible too.

Thanks for any help. Maybe someone even knows another list osax that does
it? (I've checked has's TextCommands too.)

-- 
Paul Berkowitz

ATOM RSS1 RSS2