0

I have simple php array in a php file. Here is the content :

<?php

$arr = array(
    'fookey' => 'foovalue',
    'barkey' => 'barvalue'
);

How can I fetch value foovalue using grep command ?

I have tried :

cat file.php | grep 'fookey=>'

Or

cat file.php | grep 'fookey=>*'

but always return the full line.

executable
  • 3,365
  • 6
  • 24
  • 52
  • What is `instanceid`? – Zeshan Jul 17 '19 at 07:09
  • Edited, it was my personal value – executable Jul 17 '19 at 07:09
  • So you want to grep the literal array declaration from the source code file? So this has nothing to do with PHP? – SOFe Jul 17 '19 at 07:11
  • How confident are you on the formatting consistency? For example, what if there is a line break behind `=>` before writing the value? That is also valid PHP – SOFe Jul 17 '19 at 07:13
  • After you have `grep`'d that line, pass it through a pipe to this command `awk -F' '{print $4}'`. I am on my phone right now so can't test it, if it doesn't work correctly, try $3. – Mihir Luthra Jul 17 '19 at 07:14
  • @SOFe I assume there is no line break – executable Jul 17 '19 at 07:15
  • @Mihir I got error like `Usage: awk [POSIX or GNU style options] -f progfile [--] file ...` – executable Jul 17 '19 at 07:17
  • And how confident are you on the spacing? What about no spaces or 10 spaces around `=>`? What about a `/**/` between the tokens? What about the value being a concatenation of two strings? If you are confident that all these won't happen, you could simply `cut -d"=>" -f2`, splitting the line by `=>` and taking the second part. – SOFe Jul 17 '19 at 07:17
  • @SOFe I tried it and here the output `cut: the delimiter must be a single character` – executable Jul 17 '19 at 07:18
  • @executable, must be cuz the delimiter used is `'`. Try enclosing that too. Or wait i will try on my pc. – Mihir Luthra Jul 17 '19 at 07:19
  • Oops, then cut by `>` instead of `=>` if you are confident there is no `>` in the key. But what are you trying to do here anyway? Explain what you originally wanted to do. – SOFe Jul 17 '19 at 07:19
  • The file is a default config file of a website and I need to retreive these specific data to create my custom config file from my template, then I can fill my data. I tried with `>` but now I get `'foovalue',` – executable Jul 17 '19 at 07:21
  • 1
    For the record `fookey=>*` is just a crappier way to write the regex `fookey=`. You really should read up on regular expressions before attempting to use them. The asterisk says "zero or more of the prececing" and so you are essentially saying it doesn't matter if the `>` is there or not. So you might as well not specify it at all. – tripleee Jul 17 '19 at 07:43

5 Answers5

1

Your grep command shouldn’t have worked if you are doing it just the way you posted it here. But if you are getting that line from grep whatever way you are doing,

Pass the output you got from grep through a pipe to

awk -F"'" '{print $4}'

I tested it this way on my pc:

echo "'fookey' => 'foovalue'" | awk -F"'" '{print $4}'
Mihir Luthra
  • 6,059
  • 3
  • 14
  • 39
  • I have a data like `'secret' => 'xz/v2+rAj4tQdWiKLp3jxd8sdQNo85Wq/mbypW4mIlmnB2Zu'` And it output me something like this on two line : `xz/v2+rAj4tQdWiKLp3jxd8sdQNo85Wq/mbypW4mIlmnB2Zu secret` – executable Jul 17 '19 at 07:37
  • @executable, although that works correctly on my pc. Maybe its something different version your `OS`. Try using `echo "'secret' => 'xz/v2+rAj4tQdWiKLp3jxd8sdQNo85Wq/mbypW4mIlmnB2Zu'" | cut -d"'" -f4`. Also can you show the exact output you are getting after `grep`? – Mihir Luthra Jul 17 '19 at 07:41
  • Here is what I get using `cat file.php | grep 'secret' | awk -F"'" '{print $4}'` https://justpaste.it/28ffi – executable Jul 17 '19 at 07:44
  • 1
    @executable, this simply means you have the word “secret” somewhere else too in that file. Can you please show me the output of this line `cat file.php | grep 'secret'` – Mihir Luthra Jul 17 '19 at 07:48
  • You can and generally should combine `grep` and Awk into just an Awk script. `awk -F "'" '/\047fookey\047 =>/ { print $4 }'` where `\047` is a simple way to use literal single quotes in an Awk script which itself is in single quotes. See also http://www.iki.fi/era/unix/award.html#grep – tripleee Jul 17 '19 at 07:53
  • @tripleee, thanks for the tip, i need those. (new to `awk`) :) – Mihir Luthra Jul 17 '19 at 07:57
  • @triplee Mihir thanks for the answer and I wish I could accept both answers – executable Jul 17 '19 at 08:05
  • They need the rep more than I do (-: – tripleee Jul 17 '19 at 08:08
1

grep 'fookey=>' doesn't return any matches because this regex is not matched. Your example shows a record with single quotes around fookey and a space before the =>.

Also, you want to lose the useless use of cat.

Because your regex contains literal single quotes, we instead use double quotes to protect the regex from the shell.

grep "'fookey' =>" file.php

If your goal is to extract the value inside single quotes after the => the simple standard solution is to use sed instead of grep. On a matching line, replace the surrounding text with nothing before printing the line.

sed "/.*'fookey' => '/!d;s///;s/'.*//" file.php

In some more detail,

  • /.*'fookey' => '/!d skips any lines which do not match this regex;
  • s/// replaces the matched regex (which is implied when you pass in an empty regex) with nothing;
  • s/'.*// replaces everything after the remaining single quote with nothing;
  • and then sed prints the resulting line (because that's what it always does)

If you get "event not found" errors, you want to set +H or (in the very unlikely event that you really want to use Csh history expansion) figure out how to escape the !; see also echo "#!" fails -- "event not found"

Other than that, we are lucky that the script doesn't contain any characters which are special within double quotes; generally speaking, single quotes are much safer because they really preserve the text between them verbatim, whereas double quotes in the shell are weaker (you have to separately escape any dollar signs, backquotes, or backslashes).

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • I tried the command and I got this as a result https://justpaste.it/2ayd8 – executable Jul 17 '19 at 07:43
  • Oops, missing negation, sorry about that! You want a `!` before the `d` command. Updated the answer (see the diff in Stack Overflow's revision history if you can't spot it) – tripleee Jul 17 '19 at 07:45
  • Thanks for the help but now I have the following error `-bash: !d: event not found` – executable Jul 17 '19 at 07:46
  • That's a separate error; `set +H` should fix that. I recommend that you add it to your `.bashrc` or `.bash_profile` permanently. https://stackoverflow.com/questions/11816122/echo-fails-event-not-found – tripleee Jul 17 '19 at 07:49
1

This should do:

awk -F "'" '$2~/fookey/ {print $4}' file

or in your case

awk -F "'" '$2~/secret/ {print $4}' file

It searches for all lines where second filed contains fookey/secret and the print fort field with your password.

Jotne
  • 40,548
  • 12
  • 51
  • 55
  • It output an empty line – executable Jul 17 '19 at 08:06
  • 1
    Then maybe your file is not formatted exactly as in your example. `$2` corresponds to the string between the first and the second single quote on a line; if you have additional single quotes before the keyword, that would throw this off. – tripleee Jul 17 '19 at 08:09
  • @executable Try `awk -F "'" '{print "$1="$1" $2="$2" $0="$0}' file`. If `$1` is equal to `$0` and `$2` does not show anything, you have another separator. – Jotne Jul 17 '19 at 08:16
  • @executable since `fookey` looks correct in third line, does this give you one line? `awk -F "'" '$2~/fookey/' file` – Jotne Jul 17 '19 at 08:27
  • Now it's returning like `'fookey' => 'foovalue',` – executable Jul 17 '19 at 08:29
  • @executable How com that $0 in third line does not show the complete line with `fookey`. Post your file in justpast.it – Jotne Jul 17 '19 at 08:30
  • @executable Mine commands do return `foovalue` from cut and past from this data. Try cut and past your own data from justpast.it and try again. This may also help `dos2unix filename` – Jotne Jul 17 '19 at 08:39
  • I tried again with the content from juspaste and I got the same result – executable Jul 17 '19 at 08:51
  • @executable empty result? In that case, I am not sure how to help you. Try cut and past your code to another linux computer and see how it goes. – Jotne Jul 17 '19 at 09:07
  • No, not empty, I got the following `'fookey' => 'foovalue',` – executable Jul 17 '19 at 09:09
  • @executable Then it may be that there are different `'` in use? you should only get `foovalue` if separator are correct. – Jotne Jul 17 '19 at 09:11
  • I guess yes, because I recreated a file from the justpaste – executable Jul 17 '19 at 09:12
0

You can use cut in combination with grep to get what you need.

cat file.php | grep 'fookey' | cut -c18-25

cut is used to get substring. In -cN-M, N and M are starting and ending position of the substring.

Zeshan
  • 2,496
  • 3
  • 21
  • 26
0

To fetch a value from an array why can't you use array_search method instead of grep?

<?php
$arr = array(
    'fookey' => 'foovalue',
    'barkey' => 'barvalue'
);
echo array_search("foovalue",$arr);
?>
melpomene
  • 84,125
  • 8
  • 85
  • 148
deavapriya
  • 67
  • 10
  • If you have PHP on your server, `php` is a shell command. (But I can't tell you how to use it here, I'm afraid (not)). – tripleee Jul 17 '19 at 08:16