-2

Suppose we have the following file:

John FRIEND_OF Jose
Aspirin INTERACTS_WITH Penicilin
Tree COEXISTS_WITH Grass
Andrew FIEND_OF Jane
John INTERACTS_WITH Paula

I need to print the line in reverse order if the 2nd field matches INTERACTS_WITH or COEXISTS_WITH.

Here is my AWK one-liner:

awk '{if ($2 == "INTERACTS_WITH" || $2 == "COEXISTS_WITH") print; print $3, $2, $1; next}1' test.txt

The final output is:

Jose FRIEND_OF John
Aspirin INTERACTS_WITH Penicilin
Penicilin INTERACTS_WITH Aspirin
Tree COEXISTS_WITH Grass
Grass COEXISTS_WITH Tree
Jane FIEND_OF Andrew
John INTERACTS_WITH Paula
Paula INTERACTS_WITH John

However, it is tedious to specify each condition separately like in my example above (especially if you have more conditions). I wonder how to create an array of strings (e.g., ['INTERACTS_WITH', 'COEXISTS_WITH']) and then print the line if 2nd field matches any of the elements in the array.

2
  • 1
    Why has you're output swapped John & Jose, and Andrew & Jane?
    – roaima
    Sep 20 '20 at 7:46
  • 1
    Why have you doubled up on Aspirin & Penicilin? (Once each way)
    – roaima
    Sep 20 '20 at 7:47
1

Your sample input/output is confusing at best so idk what you really want to do but here's how to specify the values you want as a string and then do something with them:

awk '
    BEGIN {
        rels = "INTERACTS_WITH COEXISTS_WITH"
        split(rels,tmp)
        for (i in tmp) {
            relSet[tmp[i]]
        }
    }
    { print }
    $2 in relSet {
        print $3, $2, $1
    }
' file
1

best I come with (can be one lined)

awk 'BEGIN { r["INTERACTS_WITH"]=1 ; r["COEXISTS_WITH"]=1} 
$2 in r {print $3,$2,$1 ; print ; next} 
{print}' ...

this is hardly a space saver.

1

Done with below script

awk '$2 ~ /INTERACTS_WITH|COEXISTS_WITH/ {$0=$3" "$2" "$1}1' filename

output

John FRIEND_OF Jose
Penicilin INTERACTS_WITH Aspirin
Grass COEXISTS_WITH Tree
Andrew FIEND_OF Jane
Paula INTERACTS_WITH John
1

You can get it using twice print changing the order of fields: {print $1, $2, $3}{print $3, $2, $1}

awk '/INTERACTS_WITH|COEXISTS_WITH/ {print $1, $2, $3}{print $3, $2, $1}' file

Jose FRIEND_OF John
Aspirin INTERACTS_WITH Penicilin
Penicilin INTERACTS_WITH Aspirin
Tree COEXISTS_WITH Grass
Grass COEXISTS_WITH Tree
Jane FRIEND_OF Andrew
John INTERACTS_WITH Paula
Paula INTERACTS_WITH John

Or more concisely:

awk '/INTERACTS_WITH|COEXISTS_WITH/ {print $0}{print $3, $2, $1}' file

Jose FRIEND_OF John
Aspirin INTERACTS_WITH Penicilin
Penicilin INTERACTS_WITH Aspirin
Tree COEXISTS_WITH Grass
Grass COEXISTS_WITH Tree
Jane FRIEND_OF Andrew
John INTERACTS_WITH Paula
Paula INTERACTS_WITH John

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.