Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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!

share|improve this question
Hmm, no 'ack' on my system to test with. Is it this program? – Hennes Jan 17 '13 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 '13 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. – Andy Lester Apr 4 '13 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 '13 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. – Andy Lester Apr 4 '13 at 13:47
up vote 4 down vote accepted

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.

share|improve this answer
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 '13 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 '13 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 '13 at 12:40

You must log in to answer this question.

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