Results 1 to 4 of 4

Thread: Help Me With this script.

  1. #1
    Join Date
    Jan 2009
    Beans
    328

    Help Me With this script.

    Hi,
    The command output:
    Code:
    root@laptop:/home/huangyingw/myproject/git/java/algorithm# fw . public
    -iname *.java -o -iname *.h -o -iname *.sh
    find . \( -iname *.java -o -iname *.h -o -iname *.sh \) -exec fgrep -wnH public {} ;
    find: invalid expression; you have used a binary operator '-o' with nothing before it.
    root@laptop:/home/huangyingw/myproject/git/java/algorithm#
    file fw.sh
    Code:
    huangyingw@laptop:~/bashrc$ cat fw.sh 
    #!/bin/bash
    FILE_POSTFIX=$HOME/bashrc/postfix.bak
    find_params=(); or="";
    while read suf
    do
      find_params+=( $or "-iname" "*.$suf" )
      or="-o"
    done < "$FILE_POSTFIX"
    echo "${find_params[@]}"
    echo find "$1" "\( ${find_params[@]} \)" -exec fgrep -wnH  "$2" {} \;
    find "$1" "\( ${find_params[@]} \)" -exec fgrep -wnH  "$2" {} \;
    file postfix.bak:
    Code:
    huangyingw@laptop:~/bashrc$ cat postfix.bak 
    java
    h
    sh
    huangyingw@laptop:~/bashrc$

  2. #2
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,499
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Help Me With this script.

    Find (and any other command) needs to see all its params as distinct words.
    let's see what find gets from your expansion
    Code:
    find_params=( -iname "*.java" -o -iname "*.h" -iname "*.sh" )
    $ i=0; for x in "\( ${find_params[@]} \)"; do echo $((++i)) \'"$x"\'; done
    1 '\( -iname'
    2 '*.java'
    3 '-o'
    4 '-iname'
    5 '*.h'
    6 '-iname'
    7 '*.sh \)'
    $ i=0; for x in "(" "${find_params[@]}" ")"; do echo $((++i)) \'"$x"\'; done
    1 '('
    2 '-iname'
    3 '*.java'
    4 '-o'
    5 '-iname'
    6 '*.h'
    7 '-iname'
    8 '*.sh'
    9 ')'
    as you can see you shouldn't glue quoted params array with anything else otherwise you will merge things together.

    that \( you often see in examples of find is equivalent to "(" or '('. It's escaped because by default bash recognizes ( and ) as syntax related and you need to make it ignore them.
    You pick one of these forms and you need to make sure it's a standalone parameter.

    you can write all commands in this form
    Code:
    some_command '(' 'param1' '-o' 'param2' ')'
    but since bash can figure out what is a word we don't have to do all that quoting, unless it has some char(s) that can break things like space,tab,;,*,?,(,) etc.
    Last edited by Vaphell; September 17th, 2012 at 07:04 AM.
    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

  3. #3
    Join Date
    Jan 2009
    Beans
    328

    Re: Help Me With this script.

    Quote Originally Posted by Vaphell View Post
    Find (and any other command) needs to see all its params as distinct words.
    let's see what find gets from your expansion
    Code:
    find_params=( -iname "*.java" -o -iname "*.h" -iname "*.sh" )
    $ i=0; for x in "\( ${find_params[@]} \)"; do echo $((++i)) \'"$x"\'; done
    1 '\( -iname'
    2 '*.java'
    3 '-o'
    4 '-iname'
    5 '*.h'
    6 '-iname'
    7 '*.sh \)'
    $ i=0; for x in "(" "${find_params[@]}" ")"; do echo $((++i)) \'"$x"\'; done
    1 '('
    2 '-iname'
    3 '*.java'
    4 '-o'
    5 '-iname'
    6 '*.h'
    7 '-iname'
    8 '*.sh'
    9 ')'
    as you can see you shouldn't glue quoted params array with anything else otherwise you will merge things together.

    that \( you often see in examples of find is equivalent to "(" or '('. It's escaped because by default bash recognizes ( and ) as syntax related and you need to make it ignore them.
    You pick one of these forms and you need to make sure it's a standalone parameter.

    you can write all commands in this form
    Code:
    some_command '(' 'param1' '-o' 'param2' ')'
    but since bash can figure out what is a word we don't have to do all that quoting, unless it has some char(s) that can break things like space,tab,;,*,?,(,) etc.
    Great.. Great thanks for your detail instructions. I have updated my script to following, and it works well and optimized now
    Code:
    huangyingw@laptop:~/bashrc$ cat fw.sh 
    #!/bin/bash
    FILE_POSTFIX=$HOME/bashrc/postfix
    PRUNE_POSTFIX=$HOME/bashrc/prunefix
    find_params=();
    prune_params=();
    or="";
    grep_params="";
    if [ -n "$3" ]
    then grep_params=" -A"$3" -B"$3;
    fi
    while read suf
    do
      find_params+=( $or "-iname" "*.$suf" )
      or="-o"
    done < "$FILE_POSTFIX"
    or="";
    while read suf
    do
      prune_params+=( $or "-iname" "*.$suf" )
      or="-o"
    done < "$PRUNE_POSTFIX"
    find "$1" "(" "${prune_params[@]}" "-o" "-iname" "find.cc" ")" -prune -o "(" "${find_params[@]}" ")" -exec fgrep -wnH  $grep_params "$2" {} \;
    huangyingw@laptop:~/bashrc$

  4. #4
    Join Date
    Jan 2009
    Beans
    328

    Re: Help Me With this script.

    Finally, my script update to be:
    Code:
    huangyingw@laptop:~/bashrc$ cat fw.sh 
    #!/bin/bash
    FILE_POSTFIX=$HOME/bashrc/postfix
    PRUNE_POSTFIX=$HOME/bashrc/prunefix
    find_params=();
    prune_params=();
    or="";
    grep_params="";
    if [ -n "$3" ]
    then grep_params=" -A"$3" -B"$3;
    fi
    while read suf
    do
      find_params+=( $or "-iname" "*.$suf" )
      or="-o"
    done < "$FILE_POSTFIX"
    or="";
    while read suf
    do
      prune_params+=( $or "-iname" "*.$suf" )
      or="-o"
    done < "$PRUNE_POSTFIX"
    find "$1" "(" "${prune_params[@]}" "-o" "-iname" "find.cc" ")" -prune -o "(" "${find_params[@]}" "-o" "-iname" "makefile" ")" -exec fgrep -wnH  $grep_params "$2" {} \;
    huangyingw@laptop:~/bashrc$

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
  •