I want to grep lines containing

 - 0 amount
 - 122,000,000 amount
 - 50,000 amount

I've tried to use

grep -rhI " - * amount ".

but it will output anything containing


regardless of whether it contains


The problem is I only want strings with

 - * amount

where * indicates anything in between - (here) amount. It is acceptable if the lines only containing " - " are dismissed.

But it doesn't work.

  • show the desired output – RomanPerekhrest May 16 '17 at 8:02
  • 1
    In regex, * isn't a wildcard but a quantifier, as ?, + and {n,m} : it qualifies the preceding token with an amount of times it can and/or must be matched. – Aaron May 16 '17 at 12:32
  • To precise what @Aaron says: in most regexp contexts :a star ( * ) means "0, 1 or n times what was just before (be it a character, or a character class, or sometimes in evolved regexp libraries, more complex things) ". a dot ( . ) means: "any character". So .* will mean any string (as it is 0, 1 or n times any character). thus: grep -rhI " - .* amount " – Olivier Dulac May 16 '17 at 13:30
  • Thank you both for giving me a better understanding of the * usage & as to why it wouldn't work in this scenario. – Thomas Bishop May 16 '17 at 15:50

The * will match zero or more of the preceding character or pattern.

This means that - * amount will match

  • - amount
  • - amount
  • - amount
  • (etc.)

To match the numbers, as you have written them, use - [0-9,]+ amount as the pattern. The + will force at least one match of the preceding regular expression, and [0-9,] will match any digit or a comma.

Given the following file:

 - 0 amount
 - 122,000,000 amount
 - 50,000 amount

 - amount
 -     amount
 - some amount

This will work:

$ grep -E -e '- [0-9,]+ amount' file
 - 0 amount
 - 122,000,000 amount
 - 50,000 amount

The -E is needed because + is an extended regular expression, and the -e is needed because otherwise the - in the pattern would be interpreted as an option to grep (-e means the next thing is a regular expression for grep to apply to its input).

You may also anchor the pattern to the start and end of the line:

$ grep -E '^ - [0-9,]+ amount$' file

This means that the -e is no longer needed and will ensure that the line starts with a space followed by the dash and the the number etc. as before. The string amount must be the last thing on the line (we anchor the word to the end of the line with $).

  • There appears to be a leading space in the file (& the pattern in the question), so -- isn't strictly necessary here, though it obviously doesn't hurt to use it anyway. – Michael Homer May 16 '17 at 8:26

Something like can do the work (with awk script, search for 1st token to be dash and 3th to be string "amount"):

awk '$1=="-" && $3=="amount" {print $2}'

If you want entire line to be printed use something like:

awk '$1=="-" && $3=="amount" {print}'

You could also use

grep -rhI -- '- [^ ]* amount' /path/to/parent/dir/*

where [^ ]* means match any number of any characters except a space.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.