Skip to main content
3 of 10
added 796 characters in body
FelixJN
  • 14.1k
  • 2
  • 36
  • 55

EDIT: following the comment, that the whole value pairs should be removed once one of them fails the requirement.

It saves each of the value pairs as element i of arrays a, b, and c, respectively; then checks for the condition and only adds the value triples to the respective fields if the conditions all apply. j just indicates if a pair is the first to make it in the output, because this does not need the semicolon as separator.

BEGIN {FS=OFS="\t"}
{
split($1,a,";")
split($2,b,";")
split($3,c,";")
j=0
for ( i in a ) {
    if (a[i]+0<-0.5 && b[i]+0>1 && c[i]+0>2) {
        if (j) { $1=$1";"a[i] ; $2=$2";"b[i] ; $3=$3";"c[i] }
        else { $1=a[i] ; $2=b[i] ; $3=c[i] ; j++}
    }
}
print $0}

Old code with misunderstood requirements:

With awk you could split the fields into arrays (called a), select desired values (into an array b), and redefine the field (print elements ob b with ;-separators).

I used a function that gets the field, operator (as string), and comparison value, then returns the new field content. As operators cannot be taken from a variable, I had to use a second function that selects the comparison operation based on the operator string (Ref at SO). This keeps you flexible for all fields and possible comparisons. I used val1+0 to ensure that contents like N/A are suppressed by forcing the variable to be numerical:

$cat script.awk
function operation(val1,operator,val2) {
    if (operator == "==" ) return val1+0 == val2
    if (operator == "<=" ) return val1+0 <= val2
    if (operator == "<" )  return val1+0 < val2
    if (operator == ">=" ) return val1+0 >= val2
    if (operator == ">" )  return val1+0 > val2
    if (operator == "!=" ) return val1+0 != val2
}

function valselect(fieldin,operator,value){
    split(fieldin,a,";") ; delete b ; blength=0
    for (i in a) {
       if (operation(a[i],operator,value)) { b[++blength]=a[i] }
    }
    fieldout=b[1]
    for (i=2 ; i<=blength ; i++) { fieldout=fieldout";"b[i] }
    return fieldout
}

BEGIN {FS=OFS="\t"}
{
$1=valselect($1,"<",-0.5)
$2=valselect($2,">",1)
$3=valselect($3,">",2)
print $0}

Then run

awk -f script.awk file

For an even more flexible approach, you may as well define the fields, operators and values in arrays and loop over them in the execution block.

FelixJN
  • 14.1k
  • 2
  • 36
  • 55