Search for files in a finder window with Regular expressions.

Edit Added the line my gracefulExit(“com.apple.finder”) under the try block when “selected from desktop is true”, in order to leave the finder window in an active state. I’m sorry.

Edit. It crosses My mind, that I haven’t tried this in column view, I only use list view or icon view, so I can’t tell really if it works in icon view. A detail here, is that I use the ctrl-F4 key to refocus the window, after the script has run, so it won’t work so well for people who has the consumer keys as their standard function keys (volume and such, without pressing “fn”.

I tried Daniel Jalkut’s script, that does this, and like it, but found it confusing at times. So I have rolled my own.
Every time you want to select items from the desktop, a new window will be opened, in your current space.

I use this from time to time on the desktop, by hitting F11 to reveal it, then you have to click on something there, to set the insertion point to the desktop. To give the script a hint, that you want to search your Desktop.

The last reg exp is remembered, and you can use unicode (utf8) characters in your search string.

So now I can perform searches like “.ø.”, or “^E.*” for that matter; which is nifty,when you just remember part of the filename, like from web archieves for instance. :wink:

It is a Perl script, named Seeker.pl that should be but into your “home/bin” folder, and an Applescript that looks for the script there. I don’t know if it works with anything less than Leopard, and it regquires that you have Perl version 5.10 or newer on your machine. You enter “perl -v” on the commandline to get the version.

NB! The perl script should be stored as utf-8 No bom.

seeker.pl:

[code]#!/opt/local/bin/perl

Copyright McUsr, and put in public domain, you are not allowed to post this elswhere. No warranties what so ever.

use 5.010 ;
use strict ;
use warnings ;
$\ = “” ; # Output record separator (print…“\n” );
$/ = “\n” ; # input record separator ; (“\n” )
$, = “”; # what is printed when there is a “,” in print statement.
$" = “§”; # List separator. ( for print @list )
$; = “” ; # Subscript separator.

my $argc = @ARGV;

if ( $argc != 2 ) {
print STDERR “Seeker: Needs a posix "/path/" and a Regexp” ;
exit 1 ;
} else {
my @results = () ;
my $pathToGlob = $ARGV[0] ;
my $regExp = $ARGV[1] ;
my @files = glob “$pathToGlob*” ;
for (my $i = 0; $i < scalar @files; $i++) {
if ( $files[$i] =~ m/./(.)$/ && $1 =~ m/$regExp/ ) {
unshift @results, $files[$i] ;
}
}
print “@results” ;
}[/code]
Seeker.scpt


# Copyright McUsr, and put in public domain, you are not allowed to post this elswhere. No warranties what so ever.
-- We store our regexp, in case *our* script runner doesn't.
property scriptTitle : "Seeker:"
property scriptpath : (path to temporary items folder from user domain as text) & "net.mcusr.regexp"
property origRegExp : ".*"
property toolsIcon : missing value
property infoIcon : missing value
property stopIcon : missing value
property searchHist : missing value
property theRegexp : missing value

on run
    global theSelectedItems, foundDesktopWindow, curInsertLoc, pathToDesktop, desktopWinIdx, selectedFromDesktop
    
    init()
    set {foundDesktopWindow, pathToDesktop, desktopWinIdx} to {false, path to desktop folder, -1}
    
    -- checks to see if there is any desktop windows
    -- and sets the index of the frontmost.
    -- also sets the current insertion location
    
    tell application "Finder"
        local fw
        set curInsertLoc to insertion location as alias
        try
            set fw to get every Finder window
        end try
        
        repeat with a in fw
            if target of a is folder pathToDesktop then
                set desktopWinIdx to index of a
                -- it is traversed by index anyway
                set foundDesktopWindow to true
                exit repeat
            end if
        end repeat
    end tell
    
    -- We do some analysis figuring if we are selecting
    -- directly from the desktop, maybe with the desktop
    -- revealed by Exposé
    
    set selectedFromDesktop to false
    if curInsertLoc is pathToDesktop then
        -- possible desktop window
        if foundDesktopWindow is true and desktopWinIdx is 1 then
            set selectedFromDesktop to false
            set apptoUse to "com.apple.finder"
        else
            set selectedFromDesktop to true
            set apptoUse to "com.apple.systemuiserver"
        end if
    else
        set apptoUse to "com.apple.systemuiserver"
        set selectedFromDesktop to false
    end if
    
    set failed to promptForNewRegxp(a reference to my theRegexp, apptoUse, "Enter Search Pattern: ", toolsIcon)
    
    if failed is true then
        my gracefulExit(apptoUse)
        
    else -- it is time to work; prepares the commadline for the do shell command
        
        storeSearchHist(my theRegexp) -- store the new regexp in searchHist
        set newRegExp to "\"" & my theRegexp & "\"" as «class utf8»
        set targetFolder to ("\"" & makePosixPath(curInsertLoc) as «class utf8») & "\"" as «class utf8»
        set myperlscript to my makePosixPath((path to home folder as text) & "bin:seeker.pl") as «class utf8»
        
        set my_shell_cmd to "perl" & space & myperlscript & space & targetFolder & space & newRegExp as «class utf8»
        
        try
            set myresult to do shell script my_shell_cmd
            
        on error e number n
            
            if (n is 255) then
                displayFailureDialog("The RegExp is Probably Malformed : ", theRegexp, stopIcon)
                my gracefulExit("com.apple.finder")
                return 0
            else
                error e number n
            end if
        end try
        
        -- We make a file list Finder can accept 
        -- Any ideas about how to coerce such a list
        -- directly, is appreciated!
        set oldDelims to AppleScript's text item delimiters
        set AppleScript's text item delimiters to {"§"}
        
        set templist to every text item of myresult as list -- «class utf8» as list
        set AppleScript's text item delimiters to oldDelims
        if templist is {} then
            displayFailureDialog("There Were No Matches: ", theRegexp, infoIcon)
            my gracefulExit("com.apple.finder")
        end if
        set theSelectedItems to {}
        repeat with a in templist
            copy POSIX file a to end of theSelectedItems
        end repeat
        
    end if
    
    tell application "Finder"
        -- if curInsertLoc = pathToDesktop, and founddesktopwindow is false
        -- or founddesktopwindow is false and  desktopWinIdx is not 1 then 
        if selectedFromDesktop is true then
            -- Whenever we get to the desktop, we create a new desktop window.
            set mw to make new Finder window
            set target of mw to folder pathToDesktop
            try
                select (every item of theSelectedItems)
            on error e number n
                error e number n
            end try
                       my gracefulExit("com.apple.finder")
        else
            -- We are selecting from the frontmost window.
            try
                tell its Finder window 1
                    select theSelectedItems
                end tell
            on error e number n
                error e number 1
            end try
            --    tell Finder window 1 to select myresult
            if not (foundDesktopWindow is true and desktopWinIdx is 1) then
                -- if it wasn't the frontmost window which was a desktop window then
                my gracefulExit("com.apple.finder")
            end if
        end if
        
    end tell
end run

to promptForNewRegxp(refToRegexp, theAppToUse, theMessage, anIcon) -- returns false for success 
    local theFail, theRetVal
    set theFail to false
    tell application id theAppToUse
        activate
        try
            set theRetVal to (display dialog theMessage default answer (my searchHist's prevRegExp) with title my scriptTitle giving up after 300 buttons {"Cancel", "Ok"} cancel button 1 default button 2 with icon anIcon)
            
            if gave up of theRetVal is true then
                set failed to true
            else
                set contents of refToRegexp to text returned of theRetVal as «class utf8»
            end if
        on error e number n
            set theFail to true
        end try
    end tell
    return theFail
end promptForNewRegxp

to displayFailureDialog(theMessage, theRegexp, anIcon)
    local res
    set theRegexp to "->" & theRegexp & "<-"
    tell application "SystemUIServer"
        activate
        try
            set res to button returned of (display dialog theMessage & theRegexp with title my scriptTitle giving up after 300 buttons {"Ok"} default button 1 with icon anIcon)
        end try
    end tell
end displayFailureDialog

to storeSearchHist(theRegexp)
    copy my searchHist to newHistItem
    copy theRegexp to newHistItem's prevRegExp
    try
        store script newHistItem in my scriptpath replacing yes
    end try
end storeSearchHist

on loadIcons(toolsIconfile, infoIconFile, stopIconFile)
    try
        set contents of toolsIconfile to a reference to file ((path to library folder from system domain as text) & "CoreServices:CoreTypes.bundle:Contents:Resources:ToolbarAdvanced.icns")
    on error
        set contents of toolsIconfile to 1
    end try
    try
        set contents of infoIconFile to a reference to file ((path to library folder from system domain as text) & "CoreServices:CoreTypes.bundle:Contents:Resources:AlertNoteIcon.icns")
    on error
        set contents of infoIconFile to 3
    end try
    
    try
        set contents of stopIconFile to a reference to file ((path to library folder from system domain as text) & "CoreServices:CoreTypes.bundle:Contents:Resources:AlertStopIcon.icns")
    on error
        set contents of stopIconFile to 3
    end try
end loadIcons

on init()
    try
        set my searchHist to load script alias (my scriptpath)
    on error
        script newSearchHist
            property prevRegExp : my origRegExp
            --    return prevRegExp
        end script
        try
            store script newSearchHist in scriptpath replacing yes
            copy newSearchHist to my searchHist
        end try
    end try
    
    if my toolsIcon is missing value then
        my loadIcons(a reference to toolsIcon, a reference to infoIcon, a reference to stopIcon)
    end if
    copy searchHist's prevRegExp as «class utf8» to my theRegexp -- we have something to work with...
end init

on gracefulExit(appbndlId) -- it hits the key ctrl-F4 Cycle through windows, to activate
    tell application "System Events" to tell process id appbndlId
        key down control
        key code 118
        key up control
    end tell
end gracefulExit

on makePosixPath(macpath)
    -- BBEditLib  @Emmanuel M. Décarie: emm@scriptdigital.com - http://scriptdigital.com/divers/bbeditlib.html
    set unixpath to POSIX path of macpath
    set unixpathlist to every character of unixpath
    repeat with i from 1 to length of unixpathlist
        -- took badchars list from http://www.macosxhints.com/article.php?story=20011217040113759 
        set badchars to {" ", "'", "!", "$", "\"", "*", "(", ")", "{", "[", "|", ";", "<", ">", "?", "~", "`", "\\"}
        set thisItem to item i of unixpathlist as text
        if thisItem is in badchars then set item i of unixpathlist to ("\\" & thisItem)
    end repeat
    set unixpath to unixpathlist as string
    return unixpath
end makePosixPath

Enjoy! :slight_smile: