Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Emulating 'locate'



DervishD <raul@xxxxxxxxxxxx> writes:

>     Hi Lloyd :)
>
>  * Lloyd Zusman <ljz@xxxxxxxxxx> dixit:
>>
>>
>> However, in that case, I target it to a specific directory tree,
>> and rarely, if ever recurse down from the root directory unless I
>> want to take a long coffee break waiting for results, and I don't
>> mind users screaming at me for slowing down the system.
>
>     ;)))))))))) I see you are not a BOFH ;))) Confess it: you like
> your users XDDD

Of course.  That's nothing to be ashamed of. :)


> [ ... ]
>
>>   find / -name specific-file -print   # 15 min 19 sec elapsed
>>   xlocate specific-file               # 28 min 40 sec elapsed
>
> [ ... ]
>
>     BTW, you seem to have a *really* big set of files...

Well, I manage a small system with around 150-160 users total, with
maybe 15-20 percent of them active at the moment.  Only a handful are
shell users; the rest are mostly email users; there are a small number
of web users, as well.  It doesn't take much to generate lots of files,
even in a modestly sized system such as this one.


>     Thanks for the code :))
>
>>   xlocate() {
>>     setopt nullglob extendedglob
>>     eval print -l ${argv[1]%/}'/**/'${^argv[2,-1]}'{,/**/*}'
>>   }
>
>     Nice! :)))

Well, I created a full-blown version with user help, meaningful error
messages, etc., and I put it into /etc/zshrc so it's available to all
the shell users on my system.  I call it 'zfind' ("zsh find"), and the
code is below.


> [ ... ]
>
> [ ... ] Thanks again for your help and suggestions :)
>
> [ ... ]
>
>     Raúl Núñez de Arenas Coronado

My pleasure.

Here's the code to my full-blown zfind function, right out of my
/etc/zshrc:

zfind() {

  local usage moreusage match oiplus1 verbose=1

  usage="\nusage: $prog [ -qhH ] dir pattern ...

  -h  =>  print a short version of help to stderr

  -H  =>  print a longer version of help to stdout (so you
          can easily pipe it through your favorite pager)

  -q  =>  suppress all error messages except for help and
          the message for illegal flags on the command line\n"

  moreusage="
  This command recursively searches under the directory tree 
  specified by 'dir' for any filesystem items whose names match 
  each the 'pattern' items that are specified.

  Its usage approximates that of the 'find' command with the '-name'
  option.

  Example:

    $0 ~ '(#i)*.{gif,png,jp{,e}g}'

    Recursively lists all items under your HOME directory whose
    names have the suffix '.gif', '.png', '.jpg', or '.jpeg'.  
    In this case (due to the '(#i)' prefix), matches are done in 
    a case-insensitve manner.

  This command makes use of zsh's extended pattern matching.
  To get more information about this, do a 'man zshexpn' and 
  look under the FILENAME GENERATION section.\n"

  while getopts qhH arg
  do
    case "${arg}" in
    q)
       verbose=
       ;;
    h)
       print -u2 "${usage}"
       return 1
       ;;
    H)
       print "${usage}${moreusage}"
       return 1
       ;;
    ?)
       print -u2 "for help, invoke \"$0 -h\" or \"$0 -H\""
       return 1
       ;;
    esac
  done

  (( $# <= $OPTIND )) && {
    print -u2 "${usage}"
    return 1
  }

  setopt nullglob extendedglob

  [[ -d ${argv[$OPTIND]} ]] || {
    [[ -n "${verbose}" ]] && {
      print -u2 "$0: directory not found: ${argv[$OPTIND]}"
    }
    return 1
  }

  (( oiplus1 = $OPTIND + 1 ))
  eval match='('${argv[$OPTIND]%/}'/**/'${^argv[$oiplus1,-1]}'{,/**/*})'

  if [[ -z "${match}" ]]
  then
    [[ -n "${verbose}" ]] && {
      print -u2 "$0: not found within \"${argv[$OPTIND]}\" tree: " \
                "${^argv[$oiplus1,-1]}"
    }
    return 1
  else
    print -l ${match}
  fi
}



--
 Lloyd Zusman
 ljz@xxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author