skip to Main Content

I am trying to read text file which contain numbers line by line in

test.txt

10.5
0.52
78.5
29.8
45
13
21.45
0.02
0.99
1.00

I want to read the number one by one and compare it with 30. I am not getting how can I do it.

I tried this but its not working.

#!/bin/bash

file=~/test.txt

while IFS= read -r line
do
    echo $line
        if [[ "$line > 30" | bc) -eq "1" ]]; then
            echo Greater
        else
            echo Smaller
        fi
done < $file

Please note: I am new to programing

4

Answers


  1. This line:

            if [[ "$line > 30" | bc) -eq "1" ]]; then
    

    should be:

            if [[ $(echo "$line > 30" | bc) -eq "1" ]]; then
    
    Login or Signup to reply.
  2. Using a pipeline of unix tools will probably be a lot faster (particularly as this only calls bc once)

    cmp=30
    
    paste test.txt <(sed "s/$/ > $cmp/" test.txt | bc) 
    | awk '{$2 = ($2 == 0) ? "Smaller" : "Greater"; print}' 
    | column -t
    
    10.5   Smaller
    0.52   Smaller
    78.5   Greater
    29.8   Smaller
    45     Greater
    13     Smaller
    21.45  Smaller
    0.02   Smaller
    0.99   Smaller
    1.00   Smaller
    

    You can feed bc multiple expressions, and it will return with one answer per line.


    If you use another shell (zsh or ksh) you don’t need any external tools:

    while IFS= read -r num; do
        printf '%st' "$num"
        (( num > 30 )) && print Greater || print Smaller
    done < test.txt
    
    Login or Signup to reply.
  3. A shell is a tool to create/destroy files and processes and sequence calls to other tools. The mandatory POSIX tool that shell has available to manipulate text (as you’re trying to do) is awk. So the right way to do what you’re trying to do in a shell is to just call awk and let awk do the rest:

    $ awk '{print $1, ($1 > 30 ? "Greater" : "Smaller")}' test.txt
    10.5 Smaller
    0.52 Smaller
    78.5 Greater
    29.8 Smaller
    45 Greater
    13 Smaller
    21.45 Smaller
    0.02 Smaller
    0.99 Smaller
    1.00 Smaller
    

    I just copied the logic from your code but of course "Smaller" should really be "Smaller or equal to".

    Read why-is-using-a-shell-loop-to-process-text-considered-bad-practice to learn the very important lesson of why not to write shell loops to manipulate text.

    Login or Signup to reply.
  4. It’s always safer to add unary "+" in front of variables and fields to ensure the comparison must be done numerically, leaving nothing to chance or implementation peculiarities

    ( it’s same as x + 0 with less verbosity; + x is a syntax error due to extra space) :

    {m,g}awk '$++NF = +__ < +$_ ? " >" : "<="' OFS='t' __=30
    
    10.5   <=
    0.52   <=
    78.5    >
    29.8   <=
    45      >
    13     <=
    21.45  <=
    0.02   <=
    0.99   <=
    1.00   <=
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search