Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

When at the command line, I find that I have to type out this command very often:

find . -iname "*php" -exec grep -H query {} \;

I'd love to set up an alias, script, or shortcut to make it work easier. I would like to do something like:

mysearch query ("*php") (.)

It would be great if the command could accept three arguments, in reverse order:

query string, file name expression, directory

If the second two arguments were omitted they would default to not being included, and the current directory.

Finally, the icing on the cake would be that if additional variables were included (4th, 5th, 6th...) they would be injected as additional arguments for the find command (like I could say -type d) at the end.

Attempted code

I tried the example below, but I'm still having trouble setting default values. What am I doing wrong?

#!/bin/bash
c=${param1+\.}
b=${param2+\*}
a=${param3+test}
find $c -iname $b -exec grep -H $a {} \;
share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

Make a shell script and add it to your PATH:

#!/bin/bash
find $3 -iname $2 -exec grep -H $1 {} \;

Name it mysearch, make it executable chmod +x mysearch, verify that it works, and add it to your path:

source

More info about parameters in bash

Edit /home/you/.bash_profile and add your script there. It should work when you type mysearch x x x. You might want to make defaults for each parameter. It's pretty easy, here's a how-to for basic and advanced uses.

EDIT: Bash param basics:

Parameters in bash are of the form $1 $2 $3, where $1 is the first parameter that you care about. There is actually a $0, but this is the name of your script as it appears on the commandline when you call it, so it isn't that important.

PARAM1=$1 PARAM2=$2

You were pretty close. Instead of c=${param1+\.} it should be: c=${1:-"."} (I think you can leave off the quotes, but it's easier to tell what a string is if you have them).

I would also do ${c} instead of $c because sometimes you need the braces, but it will never be wrong to put them everywhere.

share|improve this answer
    
I'm having trouble setting up default values, even after reading the documentation. Any tips? –  cwd Apr 6 '11 at 0:19
    
I edited my answer to show how to do defaults. (you need a :- instead of a +). –  tjameson Apr 6 '11 at 2:48
add comment

On Linux, create an alias to find a string in all files.

  1. I assume you are using something like Ubuntu 12.10.
  2. I assume your username is 'el' and your home directory is /home/el
  3. I assume you want to run the command like find . -iname $1 -exec grep -H $2 {} \; through an alias with the parameters replaced.
  4. I assume you only want to look under the current directory.

How to do that:

  1. Make a file called /home/el/findstring.sh Put these commands in there:

    #!/bin/bash
    if [ "$1" == "all" ]
    then
      echo "command:  find / -exec grep -H $2 {} \; 2>/dev/null"
      find . -exec grep -H "$2" {} \; 2>/dev/null;
    else
      echo "command:  find . -iname $1 -exec grep -H "$2" {} \; 2>/dev/null"
      find . -iname $1 -exec grep -H $2 {} \; 2>/dev/null;
    fi
    
  2. Save it and open your /home/el/.bashrc file. Add this command:

    alias fin="/home/el/bin/findstring.sh"
    
  3. Save it and make sure findstring.sh has executable permissions:

    chmod +x /home/el/bin/findstring.sh
    
  4. Source your /home/el/.bashrc like this (or just restart the terminal)

    source /home/el/.bashrc
    
  5. Create a test file called "foobar" with text "moobar" in it.

  6. Test it. cd / and type this command into the terminal:

    fin foobar moobar
    
  7. You should get this output:

    el@apollo:/$ fin foobar moobar
    command:  find . -iname foobar -exec grep -H moobar {} \; 2>/dev/null
    /home/el/foobar:moobar
    find: `/run/wpa_supplicant': Permission denied
    find: `/run/cups/certs': Permission denied
    
  8. OK so it worked and you are done. However it's also telling us we don't have permissions to search in certain directories or files.

What if you want your user to be able to search ANY file on the system regardless of owner?

You probably ran the above command as a non-root user. Lots of files you can't search if you are not root for security purposes. If you want a non root user to be able to look in any file regardless of permission, use these steps. (This is a security breach by strict standards).

  1. Create an entry in your sudoers file.

    su root
    visudo
    
  2. Add this entry:

    el ALL = NOPASSWD: /usr/bin/find
    
  3. Edit /home/el/bin/findstring.sh and add the word 'sudo' before the find command like this:

    #!/bin/bash
    if [ "$1" == "all" ]
    then
      echo "command:  find / -exec grep -H $2 {} \; 2>/dev/null"
      sudo find . -exec grep -H "$2" {} \; 2>/dev/null;
    else
      echo "command:  find . -iname $1 -exec grep -H "$2" {} \; 2>/dev/null"
      sudo find . -iname $1 -exec grep -H $2 {} \; 2>/dev/null;
    fi
    
  4. Restart the terminal and try again:

    el@apollo:/$ fin foobar moobar
    command:  find . -iname foobar -exec grep -H moobar {} \; 2>/dev/null
    /home/el/foobar:moobar
    
  5. It Works! You don't have to enter a password to see inside root owned files, and the program searched files named foobar with text 'moobar' in it. One was found and returned.

Do some real world testing:

  1. Make a directory somewhere on the filesystem, call it cats.txt, put the string "allyourbasearebelongtousnow" inside it.

  2. Run the command:

    el@apollo:/$ fin *.txt allyourbase
    command:  find . -iname *.txt -exec grep -H allyourbase {} \; 2>/dev/null
    ./home/el/cats.txt:allyourbasearebelongtousnow
    
  3. Search every file in the file system for something with 'allyourbase' in it.

    el@apollo:/home/el$ cd /
    el@apollo:/$ fin all allyourbase
    command:  find . -iname cats -exec grep -H allyourbase {} \;
    /home/el/cats.txt:allyourbasearebelongtousnow
    

    So you can't pass in a bare asterisk into my fin command. Reason being the asterisk is a reserved symbol on the terminal meaning "replace all directories and files in the correct directory here". So I set aside the word 'all' as a replacement for asterisk.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.