บล็อกเงื่อนไขเทียบกับคำสั่งตามเงื่อนไข (ถ้า)


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 โดยไม่มีอาร์กิวเมนต์จะพิมพ์ตามค่าเริ่มต้นprintprint$0


4
คุณยังสามารถเล่นกอล์ฟawk '$2!=1?$2=0:"";1' fileด้วย
terdon

@terdon: การเล่นกอล์ฟที่ดี ฉันคิดว่ามันเป็นเรื่องยากที่ OP จะเข้าใจว่า
cuonglm

1
@cuonglm nextคุณจะกรุณาอธิบายบทบาทของ ฉันเดาว่ามันจะหยุดการพิมพ์ครั้งที่สองถ้าการพิมพ์ครั้งแรกเป็นจริง สิ่งที่ต้องการในcontinue C
Alexander Cska

@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

สิ่งนี้จะทำให้บล็อกที่ไม่มีเงื่อนไขถูกข้ามถ้าบล็อกที่มีเงื่อนไขตรงกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.