Jak wyodrębnić z pliku tylko wartości większe niż próg?

10

Mam ten plik:

names average
john:15.02
Mark:09.63
James:12.58

Chcę wyodrębnić z niego tylko średnie większe niż 10, więc wynik w tym przykładzie powinien wynosić:

15.02
12.58
Haikel Fazzani
źródło

Odpowiedzi:

19

Z awk

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

Objaśnienia

  • -F:- ustawia Fseparator pola na:
  • {if($2>10)print$2}- dla każdej linii sprawdź, czy 2pole nd jest >10, jeśli tak, printto
  • <filename- pozwól powłoce otworzyć plik filename, co jest lepsze niż pozwalanie awkna to, zobacz odpowiedź Stéphane Chazelas na ten temat

Przykładowy przebieg

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

Możliwe jest również dodawanie spacji i umieszczanie wzoru poza nawiasami, więc są one równe - dzięki Stefanowi za zwrócenie na to uwagi:

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
deser
źródło
bardzo dziękuję za pomoc, idealne rozwiązanie, czy mogę w tej sytuacji używać tylko poleceń „cut” i „grep” (podstawowe polecenia), aby wyświetlać z pliku tylko średnie wyższe niż 10 ..
Haikel Fazzani
rozumiem twoje rozwiązanie, idealne, dziękuję bardzo za pomoc, doceniam wszystkie twoje wysiłki ..
Haikel Fazzani
Nie zapominaj, że bash będzie traktowany [[ $0 > 10 ]]jako leksykalne porównanie - i w każdym razie nie jest zbyt pomocny dla wartości niecałkowitych
steeldriver
@dessert: Osobiście wolę umieścić wzorzec przed instrukcjami akcji, np .: awk -F: „2 $> 10 {print 2 $}”, ponieważ dla mnie wygląda to na bardziej uporządkowane i łatwiejsze do rozszerzenia (np. 2 $> 10 i & 2 $ <100) .
Stefan
3

Z grep będziesz musiał pracować z wyrażeniami regularnymi; na przykład

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

jak w przypadku sed:

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

Ale używanie RegEx na zamówionych danych jest podatne na błędy (z mojego doświadczenia) i trudne do odczytania ;-).

Stefan
źródło
Bardzo mądry! Można skrócić do grep ':[1-9][0-9]\+\.' <file | cut -d: -f2i sed -n 's/.*:\([1-9][0-9]\+\..*\)/\1/p' <file. Warto wspomnieć, że działa to tylko z> 1,> 10,> 100 itd., Np.> 20 byłoby niemożliwe.
deser
Znalazłem błąd w moim RegEx: dla liczb bez kropki dziesiętnej RegEx musi być: ':[1-9][0-9]\+\.\?'- dosłowną kropką dziesiętną \. jest opcjonalny i dopasowywany co najwyżej \ ?. (@dessert dziękuję za wskazanie ograniczenia mojej RegEx.)
Stefan,