Bloc conditionnel vs instruction conditionnelle (if)

Disons que jai un fichier:

PRO 1 GLN 5.55112e-17 ILE -6.245e-17 THR 5.55112e-17 

Je veux que chaque ligne qui a un nombre différent de 1 dans la deuxième colonne le change à 0 et garde le reste.

Si jutilise if (ie instruction conditionnelle), tout va bien:

awk "{if($2!=1){print $1,"0"}else{print $0}}" file PRO 1 GLN 0 ILE 0 THR 0 

Mais lorsque jutilise le bloc conditionnel, quelque chose de indésirable se produit:

awk "$2!=1 {print $1,"0"} {print $0}" file PRO 1 GLN 0 GLN 5.55112e-17 ILE 0 ILE -6.245e-17 THR 0 THR 5.55112e-17 

Vous pouvez voir ce qui ne va pas.

  • Comment corriger cette erreur?
  • Pourquoi cette erreur se produit-elle?
  • Quelle est la différence entre une instruction conditionnelle et un bloc conditionnel?

Réponse

Dans un if, vous avez une else. Si if ne correspond pas, la branche else est exécutée.

Dans une instruction conditionnelle, les deux actions sont exécutée, quelle que soit la condition est vraie ou fausse.

Une solution simple:

$ awk "$2!=1 {print $1,"0";next};{print $0}" file PRO 1 GLN 0 ILE 0 THR 0 

Et vous pouvez le rendre plus concis:

$ awk "$2 != 1 {print $1,"0";next};1" file PRO 1 GLN 0 ILE 0 THR 0 

Lorsque la condition est vraie 1 et quil ny a pas daction, awk est print. print sans argument affichera $0 par défaut.

Commentaires

  • Vous pouvez également jouer au golf dans awk '$2!=1?$2=0:"";1' file.
  • @ terdon: Bon golf. Je pense quil peut être difficile de comprendre ça.
  • @cuonglm pourriez-vous sil vous plaît expliquer le rôle de next. la deuxième impression si la première est vraie. Quelque chose comme continue in C.
  • @Alexander Cska: next supprime le traitement de la ligne dentrée courante, passez à la suivante. Le même rôle que while, mais pour tout le programme awk. De plus, awk a sa propre while

réponse

Le deuxième bloc de

awk "$2!=1 {print $1,"0"} {print $0}" file 

nest pas conditionnel. Il est appliqué pour chaque ligne, et imprime donc chaque .

À la place, écrivez:

awk "$2!=1 {print $1,"0"} $2==1 {print $0}" file 

Ou écrivez:

awk "$2!=1 {print $1,"0"; next} {print $0}" file 

Cela fera sauter le bloc inconditionnel, si le bloc conditionnel est mis en correspondance.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *