15

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
26

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 '17 at 19:19
  • i understand ur solution , perfect , thank you so much for help , I appreciate all yours efforts .. Dec 18 '17 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 '17 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 '17 at 19:59
5

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 '17 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 '17 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

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.