Умовний блок проти умовного твердження (якщо)


18

Скажіть, у мене є файл:

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

Я хочу, щоб кожен рядок, який має число, неоднакове до 1, у другому стовпчику міняв його на 0 і зберігав решту.

Якщо я використовую if(тобто умовне твердження), все гаразд:

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

Але коли я використовую умовний блок, трапляється щось небажане:

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

Ви можете бачити, що не так.

  • Як виправити цю помилку?
  • Чому виникає ця помилка?
  • Чим відрізняється умовний вислів від умовного блоку?

Відповіді:


26

У ifзаяві у вас є else. Якщо ifце не відповідає, elseгілка виконується.

У умовному заяві обидві дії виконуються, незалежно від того, умова є правдивою чи помилковою.

Просте виправлення:

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

І ви можете зробити це більш лаконічним:

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

Якщо умова справжня, 1а дії немає, awkповедінка за замовчуванням є print. printбез аргументу не буде друкуватися $0за замовчуванням.


4
Ви також можете взяти в нього гольф awk '$2!=1?$2=0:"";1' file.
terdon

@terdon: Хороший гольф. Я думаю, що ОП може бути важко зрозуміти це.
cuonglm

1
@cuonglm, ви можете, будь ласка, поясніть роль next. Я думаю, це пригнічує другий друк, якщо перший правдивий. Щось на кшталт continueв C.
Олександр Цска

@Alexander Cska: nextпригнічує обробку поточного рядка введення, перехід до наступного. Така ж роль, як whileі для всієї awkпрограми. Також awkє свійwhile
cuonglm

10

Другий блок в

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

не є умовними. Він діє для кожного рядка, і таким чином друкується кожен рядок.

Замість цього напишіть:

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

Або напишіть:

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

Це призведе до того, що безумовний блок буде пропущений, якщо умовний блок буде збігатися.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.