Reputation: 530
So, I need some console tool (nothing exotic) or php function which does the following. (I don't want to write my own recursive function e.g. using file_get_contents())
I have a dir with several sub-dirs. Some of the file contain something like <?php ech $this->translate('string'); ?>
whereas string is always different.
How can i make a pattern which matches the above function and just returns me the string? Atm, I'd go with grep and exec(); and a second regex for getting my string(s). But probably, i can do it event better.
My grep example: grep -r "$this[->]translate('.*')" dir
Little question aside: How does this differ: grep -r foo dir
and grep -r foo dir/*
?
Upvotes: 0
Views: 178
Reputation: 4348
You can get just the 'string' with lookahead and lookbehind assertions:
grep -rhoP "(?<=this->translate\(')[^']*(?='\))" dir
Upvotes: 2
Reputation: 25039
Using square brackets defines character classes, while the dollar sign will be interpreted by the shell as a variable. You will have to escape them for your meaning to be correct. I might do it like this:
echo "<?php echo \$this->translate('string'); ?>" \
| grep -ho "\$this\s*->\s*translate('.*?')"
| sed "s/\$this->translate('\(.*\)')/\1/"
Where \s
stands for
The difference between grep -r <pattern> dir
and grep -r <pattern> dir/*
is somewhat subtle.
What actually happens when you run grep -r <pattern> dir/*
on the command line is that the shell will expend the dir/*
argument into a list of directory.
In essence:
grep -rho <pat> dir/*
is equivalent to:
grep -rho <pat> dir/a dir/b dir/c [etc...]
Where 'a', 'b' and 'c' are directories/files. And so grep will recurse into each of those directories and all files in dir
, but not dotfiles or dotted directory.
You are better off with grep -rho <pat> dir
, which takes all files into account.
Upvotes: 0
Reputation: 312163
Starting with your little question:
How does this differ:
grep -r foo dir
andgrep -r foo dir/*
?
The second example will not search inside child directories of dir
starting with a .
(because they won't be matched by the glob). So if you a directory that looks like this:
dir/
.a_dotted_dir/
a_visible_dir/
The first example will search inside .a_dotted_dir
while the second example will not.
How can i make a pattern which matches the above function and just returns me the string?
You can't, with grep by itself. Grep just matches patterns but does not perform any sort of processing on them. You can probably accomplish what you want by listing files that match your search pattern and processing them with sed, something like:
grep -rl "this->translate('.*')" dir |
xargs sed -n "s/.*this->translate('\([^']*\)').*/\1/p"
Also, note that I've made some changes to your regular expression. [->]
does not match ->
, and putting $this
inside double quotes will end up with the shell replacing $this
with an emptystring. You need to drop the $
, escape it, or use single quotes.
Upvotes: 1