1

I'm using the following command to parse a form element from HTML using grep. The $RESP variable contains the output from a previous curl request ...

echo $RESP | grep -m 1 -o -E 'name="id" value="([A-Za-z0-9]+)"'

It works, except it gets every instance of name="id". There's more than one instance of the form element on the page.

I tried to use the -m 1 on grep to stop at the first match, but it still returns them all.

Am I doing something wrong? I can get it working with:

echo $RESP | grep -m 1 -o -E 'name="id" value="([A-Za-z0-9]+)"' | head -n 1 | cut -d '"' -f4

But, I still can't understand why -m 1 isn't working.

Example input ...

<html>
    ...
    <input type="hidden" name="id" value="4234235325">
    ...
    ...
    <input type="hidden" name="id" value="4234235325">
    ...
    ...
    <input type="hidden" name="id" value="4234235325">
</html>

Expected output:

ID: 4234235325

As already mentioned, the form element is repeated numerous times throughout the HTML. Whether that's poor coding, or optimisation, I don't know. But the server isn't controlled by me.

10
  • You could use the -o switch to print out every match on a new line, even if one line contains multiple matches. Then filter out with head -n 1 perhaps?
    – captcha
    Commented Oct 29, 2014 at 2:01
  • have you tried substituting --max-count=NUM ? At least in my man page for grep, it's listed as alternative. Also, try to remove space between m and 1 Commented Oct 29, 2014 at 2:10
  • @Xieerqi yes, I tried those to no avail Commented Oct 29, 2014 at 2:23
  • Please provide a sample of input and desire output.
    – jimmij
    Commented Oct 29, 2014 at 2:34
  • can you put your html? Commented Oct 29, 2014 at 2:40

1 Answer 1

4

By omiting the all-important quotes around the expansion of the RESP variable, you told the shell to tear the data apart on whitespace, try to modify the data by injecting filenames, then put it together into a single line before passing it to grep. That's why grep -m1 is giving you all the matches; it's giving you the matches for the first matching line, which happens to be all of them since it's all just one line.

$ var=$'hello\nworld';
$ echo $var
hello world
$ echo "$var"
hello
world
$ echo $var | grep -m1 -o '.o'
lo
wo
$ echo "$var" | grep -m1 -o '.o'
lo

So quote the expansion. echo "$RESP" | grep .... See also http://mywiki.wooledge.org/Arguments

That said, grep, head and cut are far from the right tools for the job. Use an xml parser to parse xml. Otherwise you risk summoning the pony

1
  • Generally yes I agree that HTML shouldn't be parsed with regex. Usually I will use Python and PyQuery, or BeautifulSoup but in this instance all I needed was a simple bash script for a single task where all I had was a terminal with limited permissions. Thank you anyway :D Commented Mar 25, 2015 at 11:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .