Home > Mobile >  Subtracting columns based on greater than in bash
Subtracting columns based on greater than in bash

Time:05-05

I have a file with multiple columns:

$ cat file.txt
a bc 34 67 
t gh 68 -34
f jh -9 76
h in -66 -14
and so on 

I am trying to extract when both columns are negative; when both are positive then subtract the two columns based on which value is greater; and if either column negative then add both the columns

For both negative its quite easy: less file.txt | egrep -i "\-.*\-" | less

Expected Output:
h in -66 -14

For both positive I tried the following to no avail: less file.txt | egrep -iv "\-.*\-" | awk '($3>$4 {print $0,($3-$4)}) || ($4>$3 {print $0,($4-$3)})' | less

Expected Output:
a bc 34 67 33

For either negative, less file.txt | egrep -iv "\-.*\-" | awk '($3<0||$4<0) {print $0,($3 $4)}' | less

Expected Output:
t gh 68 -34 34
f jh -9 76  67

I am seeing this error:

awk: cmd. line:1: (FILENAME=- FNR=3208) fatal: print to "standard output" failed (Broken pipe)
egrep: write error

I know its a basic thing to do, any help would be appreciated!

CodePudding user response:

One awk idea:

awk '
$3<0 && $4<0 { print $0                          ; next }
$3>0 && $4>0 { print $0, ($3>=$4 ? $3-$4 : $4-$3); next }
             { print $0, $3 $4 }
' file.txt

NOTE: may need to be tweaked if $3==0 and/or $4==0 ... depends on OP's requirements for this scenario

This generates:

a bc 34 67 33
t gh 68 -34 34
f jh -9 76 67
h in -66 -14

CodePudding user response:

Another awk implementation:

awk '
    function abs(x) {
        if (x < 0) x = -x
        return x
    }
    $3 >= 0 || $4 >= 0 {$(NF 1) = abs(abs($3) - abs($4))} 
    {print}
' file.txt
a bc 34 67 33
t gh 68 -34 34
f jh -9 76 67
h in -66 -14

If you wanted to do this in plain bash:

abs() { echo $(($1 < 0 ? -($1) : $1)); }

while read -ra fields; do
    a=${fields[2]}
    b=${fields[3]}
    if ((a >= 0 || b >= 0)); then
        fields =($(abs $(($(abs $a) - $(abs $b)))))
    fi
    echo "${fields[*]}"
done < file.txt
  • Related