Blok bersyarat vs pernyataan kondisional (jika)


17

Katakanlah saya punya file:

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

Saya ingin setiap baris yang memiliki angka tidak sama dengan 1 di kolom kedua untuk mengubahnya menjadi 0 dan menyimpan sisanya.

Jika saya menggunakan if(yaitu pernyataan kondisional), semuanya OK:

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

Tetapi ketika saya menggunakan blok bersyarat, sesuatu yang tidak diinginkan terjadi:

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

Anda dapat melihat apa yang salah.

  • Bagaimana cara saya memperbaiki kesalahan ini?
  • Mengapa kesalahan ini terjadi?
  • Apa perbedaan antara pernyataan bersyarat dan blok bersyarat?

Jawaban:


26

Dalam sebuah ifpernyataan, Anda memiliki else. Jika iftidak cocok, elsecabang dijalankan.

Dalam pernyataan bersyarat, kedua tindakan dijalankan, terlepas dari kondisinya benar atau salah.

Perbaikan sederhana:

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

Dan Anda bisa membuatnya lebih ringkas:

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

Ketika kondisi benar 1dan tidak ada tindakan, awkperilaku default adalah print. printtanpa argumen akan mencetak $0secara default.


4
Anda juga bisa memasukkannya ke dalam golf awk '$2!=1?$2=0:"";1' file.
terdon

@terdon: Golf yang bagus. Saya pikir OP bisa sulit untuk memahaminya.
cuonglm

1
@cuonglm bisa tolong jelaskan peran next. Saya kira ini akan menekan cetakan kedua jika yang pertama benar. Sesuatu seperti continuedi C.
Alexander Cska

@Alexander Cska: nextmenekan pemrosesan jalur input saat ini, lewati ke yang berikutnya. Peran yang sama dengan while, tetapi untuk keseluruhan awkprogram. Juga, awkmemiliki sendiriwhile
cuonglm

10

Blok kedua masuk

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

tidak bersyarat. Itu ditindaklanjuti untuk setiap baris, dan dengan demikian mencetak setiap baris.

Sebaliknya, tulis:

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

Atau tulis:

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

Ini akan menyebabkan blok bersyarat dilewati, jika blok bersyarat cocok.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.