18

I have this file:

names average
john:15.02
Mark:09.63
James:12.58

I want to extract only the averages greater than 10 from it, so the output in this example should be:

15.02
12.58

3 Answers 3

30

With awk

awk -F: '{if($2>10)print$2}' <filename

Explanations

  • -F: – sets the Field separator to :
  • {if($2>10)print$2} – for each line, test whether the 2nd field is >10, if so print it
  • <filename – let the shell open file filename, that's better than letting awk do that, see Stéphane Chazelas' answer on the topic

Example run

$ <filename awk -F: '{if($2>10)print$2}'
15.02
12.58

It's also possible to add spaces and put the pattern outside the brackets, so these are equal – thanks to Stefan for pointing that out:

awk -F: '{if($2>10)print$2}' <filename
awk -F: '{ if ( $2 > 10 ) print $2 }' <filename
awk -F: '$2>10{print$2}' <filename
awk -F: '$2 > 10 { print $2 }' <filename
4
  • thank you so much for your help , perfect solution , can i use only the commands 'cut' and 'grep' (basic commands) in this situation to display from file only averages superior to 10.. Dec 18, 2017 at 19:19
  • i understand ur solution , perfect , thank you so much for help , I appreciate all yours efforts .. Dec 18, 2017 at 19:54
  • Don't forget that bash will treat [[ $0 > 10 ]] as a lexical comparison - and in any case, isn't much help for non-integer values Dec 18, 2017 at 20:24
  • @dessert: I personally prefer putting the pattern before the action statements eg.: awk -F: '$2 > 10 { print $2 }', as it looks tidier for me and easier to extend (e.g. $2 > 10 && $2 < 100).
    – Stefan
    Dec 19, 2017 at 19:59
6

With grep you'd have to work with regular expressions; e.g.

grep -E ':[^0-9]*[1-9][0-9][0-9]*\.' file | cut -d':' -f2

as with sed:

sed -n 's/.*:[^0-9]*\([1-9][0-9][0-9]*\..*\)/\1/p' file

But using RegEx on ordered data is error prone (in my experience) and difficult to read ;-).

2
  • Very clever! Can be shortened to grep ':[1-9][0-9]\+\.' <file | cut -d: -f2 and sed -n 's/.*:\([1-9][0-9]\+\..*\)/\1/p' <file. It's worth mentioning that this works with >1, >10, >100 etc. only, e.g. >20 would be impossible.
    – dessert
    Dec 19, 2017 at 7:36
  • I have found a bug in my RegEx: for numbers without a decimal point the RegEx has to be: ':[1-9][0-9]\+\.\?' - the literal decimal point \. is optional and matched at most once \?. (@dessert thanks for pointing out the restriction of my RegEx.)
    – Stefan
    Dec 19, 2017 at 20:28
0

Im posting also this solution

sed '1d' File|cut -d: -f2 |awk '$0>10' 

sed '1d' = removes the header

cut -d: -f2 = keeps values after the delimiter (: in this case)

awk '$0>10' = prints all values greater than 10

You must log in to answer this question.

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