awk: บังคับให้มีสถานะส่งคืนหรือไม่


18

นี่คือการติดตามของฉันคำถามก่อนหน้านี้

ฉันกำลังตรวจสอบจำนวนฟิลด์ใน / etc / passwd โดยใช้ snippit ที่มีประโยชน์นี้ ในตัวอย่างต่อไปนี้ผู้ใช้ 'fieldcount1' และ 'fieldcount2' มีจำนวนฟิลด์ที่ไม่ถูกต้อง:

$ awk -F: ' NF!=7 {print}' /etc/passwd
fieldcount1:x:1000:100:fieldcount1:/home/fieldcount1:/bin/bash::::
fieldcount2:blah::blah:1002:100:fieldcount2:/home/fieldcount2:/bin/bash:
$ echo $?
0

ในขณะที่คุณสังเกตเห็น awk จะออกโดยมีสถานะการส่งคืนเป็น 0 จากจุดยืนมันไม่มีปัญหาที่นี่

ฉันต้องการรวมคำสั่ง awk นี้ลงในเชลล์สคริปต์ ฉันต้องการพิมพ์บรรทัดทั้งหมดที่มีข้อผิดพลาดและตั้งรหัสส่งคืนเป็น 1 (ข้อผิดพลาด)

ฉันสามารถลองบังคับสถานะการออกเฉพาะได้ แต่จากนั้น awk จะพิมพ์เพียงบรรทัดเดียว:

$ awk -F: ' NF!=7 {print ; exit 1}' /etc/passwd
fieldcount1:x:1000:100:fieldcount1:/home/fieldcount1:/bin/bash::::
$ echo $?
1

ฉันสามารถบังคับให้ awk ออกจากสถานะกลับเป็น '1' และพิมพ์ทุกบรรทัดที่ตรงกันได้หรือไม่

คำตอบ:


23

เก็บสถานะไว้ในตัวแปรและใช้มันในENDบล็อก

awk -F: 'NF != 7 {print; err = 1}
         END {exit err}' /etc/passwd

ดีมาก. อย่างไรก็ตามฉันพบปัญหาในการรวมสิ่งนี้ไว้ในสคริปต์ทุบตี ฉันพยายามที่จะจับภาพสถานะการกลับมาของคำสั่ง awk นี้โดยการเพิ่มสิ่งที่ชอบ; echo $?หลังจากคำสั่ง awk นี้ อย่างไรก็ตามecho $?จะไม่ทำงานเพราะEND {exit err}'สิ้นสุดสคริปต์ มีวิธีตั้งสถานะการคืนสินค้าโดยไม่ออกหรือไม่?
Stefan Lasiewski

6
@StefanLasiewski exit errยุติ awk แต่ไม่ได้ยุติสคริปต์ คุณมีset -eสคริปต์นี้โดยบังเอิญไหม? ถ้าเป็นเช่นนั้นคุณได้บอกให้เชลล์ออกหากคำสั่งส่งคืนสถานะที่ไม่ใช่ศูนย์ if awk …; then echo ok; else echo fail; fiถ้าคุณต้องการที่จะทดสอบสถานะการใช้งาน
Gilles 'หยุดชั่วร้าย'

@Giles: ใช่สคริปต์นี้มีการset -eตั้งค่า นั่นอธิบายพฤติกรรมแปลก ๆ ที่ฉันเห็น ขอบคุณสำหรับการชี้ให้เห็นว่า
Stefan Lasiewski

1
หากคุณวางแผนที่จะใช้การส่งออกที่มีการทุบตีของ&&ผู้ประกอบการก็คุ้มค่าการรักษาในใจว่า"0 เป็นความจริง แต่เท็จเป็น 1 ในเปลือก"
Skippy le Grand Gourou

8

ฉันกำลังมองหาสิ่งที่คล้ายกับ Grep ซึ่งจะออกจาก 1 หากไม่พบการแข่งขัน นี่เทียบเท่ากับ Awk:

#!/usr/bin/awk -f
BEGIN {
   b1 = 1
}
index($0, "sunday") > 0 {
   b1 = 0
   print
}
END {
   exit b1
}

0

สิ่งนี้ไม่ตอบสนองความต้องการที่แน่นอนของ OP แต่ถ้าคุณสนใจเฉพาะรหัสที่ส่งคืนและไม่จำเป็นต้องพิมพ์บรรทัดที่ตรงกันเหมือนกับgrep -qคุณสามารถแก้ไข @geekasaur คำตอบเพื่อออกหลังจากการจับคู่ครั้งแรกซึ่งสำหรับอินพุตจำนวนมาก ไฟล์จะประหยัดเวลาหากข้อผิดพลาดอยู่ในช่วงต้นของไฟล์ หวังว่า/etc/passwdจะไม่ผ่านรอบคัดเลือกสำหรับคุณ!

awk -F: 'NF != 7 {err = 1; exit;}
     END {exit err}' /etc/passwd

1
awk -F: 'NF != 7 {exit 1}'จะทำเช่นเดียวกัน
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.