Page 2 of 2 FirstFirst 12
Results 11 to 20 of 20

Thread: search recursively in a particular filename

  1. #11
    Join Date
    Feb 2009
    Location
    Dallas, TX
    Beans
    6,697
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: search recursively in a particular filename

    Quote Originally Posted by ofnuts View Post
    Code:
    find -type f -iname "makefile" -exec grep -H "\.lo" '{}' \;
    +1

  2. #12
    Join Date
    Aug 2012
    Beans
    540

    Re: search recursively in a particular filename

    Quote Originally Posted by ofnuts View Post
    Replace the '*' by backslash
    Code:
    find -type f -iname "makefile" -exec grep -H "\.lo" '{}' \;
    
    "*.lo" looks for the string "*.lo", not for any string that ends with ".lo".
    Quote Originally Posted by papibe View Post
    +1
    Thanks a lot ofnuts, papibe
    But just so that I can try out a few things by myself, I have a question.
    1.Please check this link http://www.cyberciti.biz/faq/howto-f...le-under-unix/ which has this command, $ find . -type f -name '*.pl' Why is it that * works for pattern matching here?
    2.So we are using / for pattern matching in the answer you gave above ?

  3. #13
    Join Date
    Mar 2008
    Beans
    1,219

    Re: search recursively in a particular filename

    Quote Originally Posted by IAMTubby View Post
    Why is it that * works for pattern matching here?
    -name uses shell (bash) pathname expansion while -regex uses regular expressions.

    Bash pathname expansion is similar to Windows wildcards expansion but has its quirks. I'd suggest you to read Bash Manual. It's a lot of text but without it you're using a tool you know little about.

    Regular expressions are way more complex and far more powerful. Consult grap manpage (man grep command) and check Perl Manual.
    Last edited by prodigy_; May 22nd, 2013 at 03:37 PM.

  4. #14
    Join Date
    Feb 2009
    Location
    Dallas, TX
    Beans
    6,697
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: search recursively in a particular filename

    If the expressions were not quoted, all of them would fall under the same rule: bash expressions.

    However, each program has its own rules on how to expand expressions. The way to protect the expression (specially if it has asterisks) is to quote them so they are not expand by bash, and can be used by each respective program.

    In the case of the command 'find' both the -iname and -name options use very simple pattern matching. However, it has other options that allow it to use POSIX expressions (like grep). For example:
    Code:
    find -regextype posix-egrep -regex  '.*/[Mm]akefile'
    Does that help?
    Regards.

    Caveat: note that -name works over the single file name, whereas -regex matches over the whole path.

  5. #15
    Join Date
    Aug 2011
    Location
    47°9′S 126°43W
    Beans
    1,863
    Distro
    Kubuntu 12.10 Quantal Quetzal

    Re: search recursively in a particular filename

    Quote Originally Posted by papibe View Post
    If the expressions were not quoted, all of them would fall under the same rule: bash expressions.
    Mostly they would be subject to shell filename expansion in the current directory... so the search ends up being not what you think.
    If you current directory has one single foo.c in the current directory, and you want to search for other .c files in subdirectories:
    Code:
    find -name *.c
    is really seen by the find command as:
    Code:
    find -name foo.c
    since the unquoted '*.c' is expanded before find is called. So find will only return foo.c files in the subdirectories. Of course, without any .c in your current directory, the '*.c' remains '*.c' even without quotes (assuming shopt 'nullglob' is not set) so the command works, and with several *.c files, find will complain about the syntax.

    Quote Originally Posted by papibe View Post
    In the case of the command 'find' both the -iname and -name options use very simple pattern matching. However, it has other options that allow it to use POSIX expressions (like grep). For example:
    Code:
    find -regextype posix-egrep -regex  '.*/[Mm]akefile'
    Not really a good example this bash supports this type of expressions directly, and so does find in -name expressions

  6. #16
    Join Date
    Aug 2012
    Beans
    540

    Re: search recursively in a particular filename

    Quote Originally Posted by papibe View Post
    Does that help?
    Quote Originally Posted by prodigy_ View Post
    -name uses shell (bash) pathname expansion while -regex uses regular expressions.
    Quote Originally Posted by ofnuts View Post
    Mostly they would be subject to shell filename expansion in the current directory... so the search ends up being not what you think.
    Please be a bit patient with me, if I don't get it even after one more explanation, I shall go and spend a few hours reading it.

    I tried the following command to search for the word 'greptest' in all files except c files recursively from the current directory.
    find ./ -type f ! -name '*\.c' -print0 | xargs -0 -l grep 'greptest'
    But I'm getting the same output even with
    find ./ -type f ! -name '*.c' -print0 | xargs -0 -l grep 'greptest'

    Because of this, I'm not able to understand the meaning of slash(/) to represent a file ending with .c(same as my question in my previous post)

    I'm sorry to ask the question again, but I'm still finding it a bit difficult even after writing a few commands.

    Thanks.

  7. #17
    Join Date
    Aug 2012
    Beans
    540

    Re: search recursively in a particular filename

    i was able to figure it out, please wait for a few minutes for me to post my answer/understanding and then you may reply

  8. #18
    Join Date
    Aug 2012
    Beans
    540

    Re: search recursively in a particular filename

    Sorry for multiple spams by me, but this is my understanding.My question was why slash(/) is used

    What I understand is that,
    * ? . etc are special characters.
    If you want the following meanings, then you need not mention any slash etc. ie, "*c" would mean anything ending with c, like ''spec''
    Code:
     (dot)will match any single character, equivalent to ? (question mark) in standard wildcard expressions. Thus, "m.a" matches "mpa" and "mea" but not "ma" or "mppa".
    \ (backslash)is used as an "escape" character, i.e. to protect a subsequent special character. Thus, "\\" searches for a backslash. Note you may need to use quotation marks and backslash(es).
    .* (dot and asterisk)is used to match any string, equivalent to * in standard wildcards.
    * (asterisk)the proceeding item is to be matched zero or more times. ie. n* will match n, nn, nnnn, nnnnnnn but not na or any other character.
    ^ (caret)means "the beginning of the line". So "^a" means find a line starting with an "a".
    $ (dollar sign)means "the end of the line". So "a$" means find a line ending with an "a".
    For example, this command searches the file myfile for lines starting with an "s" and ending with an "n", and prints them to the standard output (screen):
    But, if you want a word to contain a pattern like "*c", then your pattern should be like "\*c"
    Similarly, if you want to accommodate the pattern like word ending with the extension ".lo", your pattern should be like "\.lo"

    Thanks a lot. Please correct me if I'm wrong.

  9. #19
    Join Date
    Apr 2012
    Beans
    5,386

    Re: search recursively in a particular filename

    PMJI

    That's not really it - the difference is whether you are using a regex based search or a glob based search. For example if we have

    Code:
    $ ls
    myfile.c
    Code:
    $ find . -name '*.c'
    ./myfile.c
    is a glob-style pattern match, in which * means any characters and . means a literal period; whereas

    Code:
    $ find . -regex '.*\.c'
    ./myfile.c
    is a regex based search in which . means "any single character" and * means "zero or more instances of the previous regex" and \. means a literal period. If you try

    Code:
    $ find . -regex '*.c'
    it doesn't work because the symbols are interpreted with their regex meanings. However

    Code:
    $ find . -name '*\.c'
    ./myfile.c
    does work, because it's OK to escape the period (even though in this case it doesn't need escaping because -name is a non-regex predicate).

    Hope this helps

  10. #20
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,325
    Distro
    Ubuntu 10.04 Lucid Lynx

    Re: search recursively in a particular filename

    Code:
                             GLOB                     REGEX
                      ( shell file matching     ( sed, grep, awk, perl, ...
                        find -name )              find -regex )
    --------------------------------------------------------------------------------------
    line start                                        ^
    line end                                          $
    dot                       . (\. works too)        \. or [.]
    any char                  ?                       .
    any sequence              *                       .*
    escaped (literal) X       \X                      \X
    'a' or 'b' or 'c'         [abc]                   [abc]
    a-z, A-Z                  [a-zA-Z]                [a-zA-Z]
    0-9                       [0-9]                   [0-9]
    not-XYZ                   [^XYZ]                  [^XYZ]
    'abc' or 'def'                                    abc|def 
    0-or-more of X                                    X*  
    0-or-1 of X                                       X?
    1-or-more of X                                    X+
    X n times                                         X{n}
    X n-m times                                       X{n,m}

    there are also POSIX char classes like [:space:],[:alpha:],[:digit:] etc. supported by both globs and regexes
    http://www.regular-expressions.info/posixbrackets.html
    \X in general means escaped X, eg \.='.', \[ = '[' but at least some flavors of regexes also support shorthands for char classes eg
    Code:
    \s = whitespace     \S = not-whitespace
    \d = digit          \D = not-digit
    \w = word-chars     \W = not-word-chars
    regex flavors differ in things like meaning of + vs \+ (some consider + as quantifier and \+ as literal +, other do the opposite), {} vs \{\}, personally i go with ones that have the special meaning as default, i hate seeing loads of \'s
    sed -r
    grep -E(xtented) or grep -P(erl)
    find -regextype posix-extended
    Last edited by Vaphell; May 22nd, 2013 at 10:04 PM.
    if your question is answered, mark the thread as [SOLVED]. Thx.
    To post code or command output, use [code] tags.
    Check your bash script here // BashFAQ // BashPitfalls

Page 2 of 2 FirstFirst 12

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •