How can I search my entire drive for a file without getting recursively stuck in /Volumes?

Solution 1:

Use locate, grep or find at the command line.

Open Applications>Utilities>Terminal and either use:

  1. sudo locate -0 '*.txt' | xargs -0 grep WORD 2>/dev/null

    Substitute WORD with the word you want to search for. This is by far the fastest method.

    I'd recommend to recreate the locate database first to improve accuracy:

    sudo /usr/libexec/locate.updatedb

    Note that on OS X, the locate database is created by user nobody. That means that files hidden to nobody won't be indexed. You can modify /usr/libexec/locate.updatedb and comment out (that is, prefix with #) this section:

    if [ "$(id -u)" = "0" ]; then
         rc=0
         # 2013-03-08 jaume Correct mktemp
         export FCODES=`mktemp --tmpdir updatedbXXXX`
         chown nobody $FCODES
         tmpdb=`su -fm nobody -c "$0"` || rc=1
         if [ $rc = 0 ]; then
             install -m 0444 -o nobody -g wheel $FCODES /var/db/locate.database
         fi
         rm $FCODES
         exit $rc
     fi
    

    so that it is indexed under user root (this applies to OS X 10.8 (Mountain Lion), on other OS X versions locate may index files differently).

  2. sudo grep -R --exclude-dir '/Volumes/<OS volume>' --exclude-dir '/Volumes/MobileBackups' --exclude-dir '/.Spotlight*' --exclude-dir '/.MobileBackups' --exclude-dir '/.DocumentRevisions*' --include '*.txt' WORD / 2>/dev/null

    Substitute WORD with the word you want to search for and <OS volume> with the name of your OS volume. The grep options used are:

    • -R: does a recursive search in the specified path, that is, in /. If you search your TimeCapsule backup, replace / with something like /Volumes/TimeCapsule.

    • --exclude-dir: excludes the specified folders. As you see, I exclude Spotlight, the Versions folder and local TimeMachine folders. If you want to search your local drive only while your TimeCapsule is mounted, add --exclude-dir /Volumes/TimeCapsule.

    • --include '*.txt': tells grep to search files which match *.txt.

    Additionally:

    • 2>/dev/null: sends errors to /dev/null so that you don't see them.
  3. sudo find / ! -path '/.Spotlight*' ! -path '/Volumes/<OS volume>/*' ! -path '/Volumes/MobileBackups/*' ! -path '/.MobileBackups/*' ! -path '/.DocumentRevisions*' -name *.txt -type f -exec grep -H WORD {} + 2>/dev/null

    Again, substitute WORD with the word you want to search for and <OS volume> with the name of your OS volume. As before, 2>/dev/null sends errors to /dev/null so that you don't see them, and if you search your TimeCapsule backup, replace / with something like /Volumes/TimeCapsule.

    The find options used are:

    • ! -path: exclude paths specified. If you want to search your local drive only while your TimeCapsule is mounted, add ! -path /Volumes/TimeCapsule/*.

    • -name *.txt: search files named *.txt. As you see, I exclude Spotlight, the Versions folder and local TimeMachine folders.

    • -type f: search only files, ignore symlinks, folders, etc.

    • grep -H WORD {}: grep file for WORD. -H forces grep to print the filename.

The output of any of the commands above looks like this:

filename: matched line

for example, when searching for 'GNU':

/usr/local/share/doc/p7zip/DOCS/readme.txt:7-Zip is free software distributed under the GNU LGPL 
/usr/local/share/doc/p7zip/DOCS/readme.txt:1) You can compile and use compiled files under GNU LGPL rules, since 
/usr/local/share/doc/p7zip/DOCS/readme.txt:  copying.txt    - GNU LGPL license
/usr/local/share/doc/xz/history.txt:    Alexandre Sauvé helped converting the build system to use GNU

If you want to do a case insensitive search, replace grep with grep -i above.