views:

76

answers:

2

I am looking for a shell script which scans a direcotry and all its subdirectories for .php and .phtml files. Within these files, I am looking for $this->translate('') statements (also $this->view->translate('')) and I want to save the content of these statements in a textfile.

The problem is, that there are several different types of this statements:

  • $this->translate('Single Quotes') // I need: Single Quotes
  • $this->translate("Double Quotes") // I need: Double Quotes
  • $this->translate('Single quotes with %1$s placeholders', $xy) // I need: Single quotes with %1$s placeholders
  • $this->translate("Double quotes with %1\$s", $xy) // I need: Dobule quotes with %1$s
  • $this->view->translate('With view') // I need: With view
  • $this->view->translate("With view 2") // I need: With view 2
  • $this->translate('Single Quotes with "Doubles"') // I need: Single Quotes with "Doubles"
  • $this->translate("Double Quotes with 'Singles') // I need: Double Quotes with 'Singles'

I have already programmed a script and a guy from starmind.com sent me the following lines:

 echo -n > give_me_your_favorite_outfile_name.txt

for i in `find . -iname '*php' `
do
    echo -n "Processing $i ..."
#    echo  "    +++++++ from $i ++++++++" >> give_me_your_favorite_outfile_name.txt
   cat $i | sed -n -e '/->translate(*/p' | sed -e 's/\(.*->translate(.\)\([a-z A-Z \d092\d039\d034]*\)\(.*\)/\2/g' | sed -e 's/\(.*\)\(\d039\)/\1/g' | sed -e 's/\(.*\)\(\d034\)/\1/g' >> give_me_your_favorite_outfile_name.txt
    echo " done"
done

for i in `find . -iname '*phtml' `
do
    echo -n "Processing $i ..."
#    echo "    +++++++ from $i ++++++++" >> give_me_your_favorite_outfile_name.txt
    cat $i | sed -n -e '/->translate(*/p' | sed -e 's/\(.*->translate(.\)\([a-z A-Z \d092\d039\d034]*\)\(.*\)/\2/g' | sed -e 's/\(.*\)\(\d039\)/\1/g' | sed -e 's/\(.*\)\(\d034\)/\1/g' >> give_me_your_favorite_outfile_name.txt
    echo " done"
done

Unfortunately, it does not cover all the above cases, especially the Quotes within Quotes cases. As I am not a shell expert at all and need that script for a verification process, I would be very happy to get help from you guys.

Important: It has to be written in Shell. A PHP Version exists.

+1  A: 
find /path -type f \( -name "*.php" -o -name "*.phtml" \) | while IFS= read -r -d $'\0' file
 do
    while read -r line
    do
    case "$line" in
        *'$this->translate'* | *'$this->view->translate'* )
        line="${line#*this*translate(}"
        line="${line%%)*}"
        case ${line:0:1} in
            \$) s=${line:0};;
             *) s=${line:1:${#line}-2};;
        esac
        case "$s" in
           *[\"\'],* )
            s=${s/\\/}
            echo ${s%%[\"\'],*};;
           * ) echo "$s";;
        esac
    esac
    done < "$file"
 done
hi levisthanks for your help. It works almost perfect. I found two exceptions where it does not work:1. If it is written $this->translate("%1\$s todo", $x), than I need %1$s without te backslash.2. One thing I forgot to mention in the question (sorry!): If the translate operation contains only a variable (e.g. $this->translate($label) but not a string it should be skipped.
Marc
This script does not properly handle files names with whitespace in their names. Please see http://mywiki.wooledge.org/BashFAQ/020 on how to do that properly.
SiegeX
+1  A: 

This does it using sed in a Bash while loop and demonstrates another way to do the find for variety's sake:

find . -iregex ".*\.php\|.*\.phtml" |
    while read f
    do
        sed -n '/[\"\o047]/ {s/$this->\(view->\|\)translate([\"\o047]\(.*\)[\"\o047].*)/\2/; s.\\..;p}' $f
    done > outputfile.txt

Edit:

To take care of other text on the line change the sed command to this:

sed -n '/[\"\o047]/ {s/.*$this->\(view->\|\)translate([\"\o047]\(.*\)[\"\o047].*).*/\2/; s.\\..;p}' $f

(Just add a .* at the beginning and end of the search string.)

Dennis Williamson
does this take care of strings before "$this" and after translate's ")" ?
hi levis. thanks for that submission. unfortunately, the outputfile stays empty...
Marc
@Marc: You said "levis" in your comment here, but were you referring to my `sed` answer? If you do the sed command directly on a php file without the `find` or redirection (`sed -n '...' something.php`) do you get any output to the screen? Any error message? Perhaps the `find` is not working. Try a more straightforward `find`.
Dennis Williamson
hi dennis! I'm sorry to call you levis. Yes, it has something to do with the find because the find itself does not return anything..
Marc
Try it using the find command as shown in levislevis85's answer.
Dennis Williamson
hi dennis. if I use the find of levis and your script, I get the following error: extra characters at the end of p commandyou know why?
Marc
actually. this is the whole error (many many times): sed: 1: "/[\"\o047]/ {s/.*$this- ...": extra characters at the end of p command
Marc
I don't know. Copy/paste the end of the line (this part: `; s.\\..;p}' $f`) into a comment here and let me see if I see something.
Dennis Williamson