Find the answer to your Linux question:
Results 1 to 10 of 10
Hello, I'm searching large directories of undocumented .c and .h files, and I need to find where a function is located. I found this in an earlier thread: Code: find ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Sep 2009
    Posts
    7

    [SOLVED] How do I search strings from multiples files AND get the file where it's loc


    Hello,

    I'm searching large directories of undocumented .c and .h files, and I need to find where a function is located.

    I found this in an earlier thread:

    Code:
    find <search_dir> -name <pattern> -exec grep <search_string> '{}' \;
    But it doesn't tell me the file where it found the <search_string>, just outputs the line. How do I get the filename?

    -Stephen

  2. #2
    tpl
    tpl is offline
    Linux User
    Join Date
    Jan 2007
    Location
    cleveland
    Posts
    478
    grep is the one--

    "grep <pattern> *.c"

    or with -n it'll tell you what line number
    the sun is new every day (heraclitus)

  3. #3
    Just Joined!
    Join Date
    Sep 2009
    Location
    Calgary, Alberta, Canada
    Posts
    2

    Add -r for recursive

    One solution is to separate find and grep. Use find to get the directory location, Once you know where the directory is, go to the directory and grep for the pattern recursively.

    grep -r <pattern> *

    -r for recursive, this way if a directory is found in the current directory, the subdirectory will also be traversed. This will definitely show you where the pattern lives.

  4. $spacer_open
    $spacer_close
  5. #4
    Linux Guru
    Join Date
    Nov 2007
    Location
    Córdoba (Spain)
    Posts
    1,513
    Just use grep. By default it should show file name when you are greping multiple files (ie. you use a wildcard). To show the line number use -n. For example, if I search for a word on the linux kernel source tree I get:

    Code:
    $ grep -n -r -i -w **** *
    Documentation/DocBook/kernel-hacking.tmpl:1306:         * give up.  I'm serious, I am going to kick the living ****
    arch/mips/include/asm/mipsprom.h:29:/* More PROM ****.  Probably has to do with VME RMW cycles??? */
    arch/mips/kernel/genex.S:95:     * Big ****, we now may have two dirty primary cache lines for the same
    arch/sparc/kernel/pcic.c:497:                            * to **** into regions like that.
    arch/sparc/kernel/traps_64.c:282:               /* ****... */
    arch/sparc/lib/checksum_32.S:327:        * give up.  I'm serious, I am going to kick the living ****
    arch/sparc/mm/srmmu.c:1608:      * this **** off... nice job Fujitsu.
    arch/sparc/mm/ultra.S:24:        * in Microelectronics who refused to fix this ****.
    arch/x86/kernel/visws_quirks.c:305:      * What lunatic came up with this ****?
    drivers/ata/sata_via.c:316: *   SCR registers on vt6420 are pieces of **** and may hang the
    drivers/block/ub.c:1093:                                 * This is typically ENOMEM or some other such ****.
    drivers/net/declance.c:32: *      v0.007: Big ****. The LANCE seems to use a different DMA mechanism to
    drivers/net/sunhme.c:930:       /* Remember: "Different name, same old buggy as **** hardware." */
    drivers/net/sunlance.c:51: *              This was the sun4c killer. ****, stupid bug.
    drivers/net/wan/z85230.c:1600:                  ct=2;   /* **** happens.. */
    drivers/net/wireless/iwlwifi/iwl3945-base.c:3677:       /* all this **** doesn't belong into sysfs anyway */
    drivers/staging/slicoss/slicoss.c:1302: u32 c;          /*  CRC **** reg                 */
    drivers/staging/slicoss/slicoss.c:2147:                     we wouldn't need this ****
    drivers/staging/sxg/sxg.c:3496: u32 c;                  /*  CRC **** reg */
    drivers/video/aty/radeon_pm.c:284:      /* Hrm... same ****, X doesn't do that but I have to */
    fs/jffs2/dir.c:858:             /* Oh ****. We really ought to make a single node which can do both atomically */
    fs/notify/fsnotify.c:165:                               /* ****, we OOM'd and now we can't tell, maybe
    net/ipv4/tcp_input.c:692:        *    all the algo is pure **** and should be replaced
    [...]
    Edit: It seems the "****" word has been censored. In the example grep command I posted, The four asterisks represent whatever word you want to search for. The last one is a true asterisk which means to grep into all files.

  6. #5
    Just Joined!
    Join Date
    Sep 2009
    Posts
    7
    Thanks,

    So a follow-up questions is how can I replace that word in all the files?

    I presume there's some shell scripting and pipelines involved... but I wouldn't even know where to start.

    -S!

  7. #6
    Linux Guru
    Join Date
    Nov 2007
    Location
    Córdoba (Spain)
    Posts
    1,513
    Code:
    # we have 6 files
    $ ls
    a  b  c  d  e  f
    # only e and f contains the string "foo"
    $ grep -l foo *
    e
    f
    # we pipe the output of grep into a while loop
    # and then edit it with sed -i, the -i is important
    # otherwise the resultant file will be empty
    $ grep -l foo * | while read file; do sed -i 's/foo/bar/g' "$file"; done
    $ cat e f
    bar
    bar

  8. #7
    Just Joined!
    Join Date
    Sep 2009
    Posts
    7
    Okay,

    So a script that looked like:

    Code:
    #!/bin/bash
    # This is file grename
    
    OLDTEXT=${1}
    NEWTEXT=${2}
    
    grep -l "${OLDTEXT}" * |
    while read file
    do
        sed -i 's/${OLDTEXT}/${NEWTEXT}/g' "$file"
    done
    would do the same thing?

    grename foo bar

  9. #8
    Linux Guru
    Join Date
    Nov 2007
    Location
    Córdoba (Spain)
    Posts
    1,513
    It seems ok. However, you should quote "$1" and "$2", the brackets are not needed there, though they certainly don't harm either.

  10. #9
    Just Joined!
    Join Date
    Sep 2009
    Posts
    7
    Hrmmm... it's not replacing anything. Do I need a 's/%foo/bar/g' or 's/#foo/bar/g'? I've seen that elsewhere.

    afaik, none of the files are write-protected.

    Edit:
    The prompt version works, just not the script file. Oh well. thanks for the help, refactoring this just got a lot easier!!

    -S!

  11. #10
    Linux Guru
    Join Date
    Nov 2007
    Location
    Córdoba (Spain)
    Posts
    1,513
    Try with some extra quoting in sed,

    Code:
    #!/bin/bash
    # This is file grename
    
    OLDTEXT=${1}
    NEWTEXT=${2}
    
    grep -l "${OLDTEXT}" * |
    while read file
    do
        sed -i 's/'"${OLDTEXT}"'/'"${NEWTEXT}"'/g' "$file"
    done

Posting Permissions

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