Khối điều kiện so với tuyên bố điều kiện (nếu)


17

Nói rằng tôi có một tập tin:

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

Tôi muốn mỗi dòng có số không bằng 1 trong cột thứ hai để thay đổi thành 0 và giữ phần còn lại.

Nếu tôi sử dụng if(tức là tuyên bố có điều kiện), mọi thứ đều ổn:

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

Nhưng khi tôi sử dụng khối có điều kiện, một cái gì đó không mong muốn sẽ xảy ra:

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

Bạn có thể thấy những gì sai.

  • Làm cách nào để khắc phục lỗi này?
  • Tại sao lỗi này xảy ra?
  • Có gì khác nhau giữa một câu điều kiện và một khối có điều kiện?

Câu trả lời:


26

Trong một iftuyên bố, bạn có một else. Nếu ifkhông khớp, elsenhánh được thực thi.

Trong một tuyên bố có điều kiện, cả hai hành động đều được thực thi, bất kể điều kiện là đúng hay sai.

Một sửa chữa đơn giản:

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

Và bạn có thể làm cho nó ngắn gọn hơn:

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

Khi điều kiện là đúng 1và không có hành động, awkhành vi mặc định là print. printkhông có đối số sẽ được in $0theo mặc định.


4
Bạn cũng có thể đánh gôn vào awk '$2!=1?$2=0:"";1' file.
terdon

@terdon: Chơi golf tốt. Tôi nghĩ rằng OP có thể khó hiểu điều đó.
cuonglm

1
@cuonglm bạn có thể vui lòng giải thích vai trò của next. Tôi đoán nó sẽ loại bỏ bản in thứ hai nếu bản đầu tiên là đúng. Một cái gì đó như continuetrong C.
Alexander Cska

@Alexander Cska: nextngăn chặn xử lý dòng đầu vào hiện tại, chuyển sang dòng tiếp theo. Vai trò tương tự while, nhưng cho toàn bộ awkchương trình. Ngoài ra, awkcó riêng của nówhile
cuonglm

10

Khối thứ hai trong

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

không có điều kiện. Nó được áp dụng cho mọi dòng, và do đó in ra mỗi dòng.

Thay vào đó, hãy viết:

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

Hay viết:

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

Điều này sẽ khiến khối vô điều kiện bị bỏ qua, nếu khối điều kiện được khớp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.