I have a text file demo.txt like below.

This is a line with id (9)
This (8) is another line with id
(10) This is a line with id too
11 This line does nothing

The file has some lines with id scattered randomly. The id pattern is number with parenthesis.

My job is to find the largest id in this file so that I know what the next id is when adding a new line.

My previous work

ack-grep demo.txt -o --match '\(\d+\)' | sort -r | head -n 1

The result is (9) but not (10) as my expectation. I think the reason is sort regards the output as text because they have parenthesis.

The question is: How can I output only the number from ack or grep for later sorting but still matching the pattern(parenthesis in my example)?

Thanks a lot!

  • Hmm, no 'ack' on my system to test with. Is it this program? betterthangrep.com/install
    – Hennes
    Jan 17, 2013 at 12:20
  • @Hennes, yes, it's that program. And in Ubuntu the name is act-grep. There is a package apt-get install ack-grep. I myself found act more stable than grep.
    – Billy Chan
    Jan 17, 2013 at 12:22
  • @BillyChan: You mean ack-grep and ack, not act-grep and act. And how do you mean that ack is more stable than grep? I'm the author of ack and I certainly wouldn't make such a claim. Apr 4, 2013 at 4:04
  • @AndyLester, thanks for your nice work on ack. I used grep before but sometimes met weird errors, then I switched to ack and such errors disappeared. So I added such claim on my notes but really could not recall the cases for the errors.
    – Billy Chan
    Apr 4, 2013 at 5:24
  • ack and grep behave differently. For one, ack won't look in binary files unless you very specifically ask it to, so maybe the errors you were getting were warnings about searching binary data. Apr 4, 2013 at 13:47

1 Answer 1


grep can't be used to output parts of a match, but why not get rid of the parentheses?

This works for GNU grep:

grep -P '\(\d+\)' -o demo.txt | sed 's/[()]//g' | sort -nr | head -n1

The following also work for BSD grep, which you can use on OS X, for example:

grep -E '\([[:digit:]]+\)' -o demo.txt | …    
grep -E '\([0-9]+\)' -o demo.txt | …

To get the result we want, we add the -n argument to sort to sort numerically, which gives you 10 as the first result.

  • 1
    For completeness sake (though I prefer default installed packages over extra installed perl scripts): ./ack-grep demo.txt -o --match '\(\d+\)' | sed 's/[()]//g' | sort -nr | head -n 1 (Using slhk's sort and sed).
    – Hennes
    Jan 17, 2013 at 12:35
  • Yes, I figured I'd use the default grep since not everyone might have ack-grep, but the first command can easily be replaced of course.
    – slhck
    Jan 17, 2013 at 12:36
  • slhck, The answer works perfectly. The sed command is so smart. Thanks a lot! @Hennes, thank you too!
    – Billy Chan
    Jan 17, 2013 at 12:40

You must log in to answer this question.

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