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.

I am attempting to use the find command and came across an article at http://www.linux.ie/newusers/beginners-linux-guide/find.php which states:

The wildcard character is escaped with a slash so BASH sends a literal asterisk to the find utility as an argument instead of performing filename expansion and passing any number of files in as arguments.

for the command find . -name up\*.

Being new to the world of Linux I don't quite understand how the use of a backslash which is meant to escape the meta character * is interpreted and returns results as though as it is being passed to find. Does it mean if I use the -name option I have to use a backslash to pass a wildcard and if I don't use -name I don't have to use a backslash? Also is the backslash being used so that the bash shell doesn't attempt to expand it?

share|improve this question

2 Answers 2

up vote 1 down vote accepted

Be aware that you are using the term "regular expression" rather loosely.. What you are dealing with in the find -name option is rather close in behaviour to a shell glob... On the other hand, the find -regex option uses a regular-expression search. You can choose which style of regex to use via the -regextyp option.. The choice of currently-implemented types is: emacs (this is the default), posix-awk, posix-basic, posix-egrep and posix-extended. ...

How you deal with the backslash and asterisk, etc. can vary depending on what you want to do.  If you want find -name to consider it an asterisk as a wildcard character, then you need to ensure that it is NOT escaped when find actually reads the pattern from the command line.

To ensure that find gets it in an unescaped form, you must prevent the shell (typically bash) from performing it's *(very powerful) shell expansion on your asterisk... To protect it you MUST escape it at the command-line level (ie. "escape it" in the eyes of the shell).. The key concept at this point is "protect"...

You can protect your asterisk from the shell in three ways:

  • use 'single quotes'
  • use "double quotes"
  • use a \ backslash (and no quotes)

So, for find to see your asterisk as a wildcard, any of the following "protection" methods will work.

  • find -name up'*'
  • find -name up"*"
  • find -name up\*
  • find -name 'up*'
  • find -name "up*"
  • find -name "up"\*

Note that the shell will never perform expansion on anything in 'single quotes' ... "double quotes" are a different story..

share|improve this answer
    
One of the best answers. Forgive my n00bness but am confused by the statement then you need to ensure that it is NOT escaped when find actually reads the pattern from the command line. and the followed by To protect it you MUST escape it at the command-line level. Further confounded by Note that the shell will never perform expansion on anything in 'single quotes' ... "double quotes" are a different story.. So looking at the first statement you mention it must not be escaped –  PeanutsMonkey Sep 10 '12 at 17:52
    
but followed by that you mention escaping it at a command-line level which I assume means within the command itself e.g. find . -name up\*. This is further compounded by the last statement where you mention no expansion is made on anything with single quotes. Do you mean that the bash shell does not expand anything with single quotes but the find command does? –  PeanutsMonkey Sep 10 '12 at 17:54
1  
Yes, 'in single quotes' refers to the shell, ie. the command-line. A called app (like 'find') is free to process your asterisk (internally) as it sees fit. Getting it into find as a simple asterisk, which is what you need in this situation, is the type of thing you always need to be alert to. The bash shell can do some amazing pre-processig of things on the command-line, but you need to manage it.. Quotes and backslash are the control mechanisms. find -name up\* and 'up*' protect the asterisk from the shell. If it wasn't protected, it would expand to (many) matching filenames. –  Peter.O Sep 10 '12 at 20:11
    
... Once inside find's domain, the asterisk is a literal asterisk again (ie, it is NOT escaped)... The bash command-line "protection" methods (quotes/backslash) are discarded by bash; they are only there as indicators to bash as to how to handle its command-line expansions ... There are 6 categories of shell expansion: 1. brace expansion 2. tilde expansion 3. parameter expansion 4. variable expansion 5. word splitting 6. pathname expansion –  Peter.O Sep 10 '12 at 20:28
    
So assuming I did not escape the meta characters e.g. * does this mean that the command find . -name up* would be interpreted by both the bash shell as well as find? Secondly when you say discarded, what do you mean exactly? Lastly would you mind elaborating on the 6 categories of shell expansion? –  PeanutsMonkey Sep 10 '12 at 22:10

What you're missing here is that both the shell and find expand *. You want find to expand it, so you need to hide it from the shell.

You're looking for all the files off the current directory whose names begin with "on", right? If you let the shell expand the *, you won't get that. Suppose your current directory contains the files "upwards" and "uplift". Then the shell changes your command to

find . -name upward uplift

which is bad syntax for find. If there are no matching files, then the shell leaves the argument alone — but it's good to get into the habit of using commands that work right regardless of details like that.

share|improve this answer

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.