ฉันจะประมวลผลหลายระเบียนด้วย awk ในสคริปต์ทุบตีได้อย่างไร


14

example.txt อยู่ด้านล่าง

Restaurant: McDonalds 
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

Restaurant: 5 guys
City: Atlanta
State: Georgia
Address: 123 Peachtree Rd
Phone: 911

Restaurant: KFC
City: NYC
State: NY
Address: 123 Madison Square
Phone: 911

ฉันใช้ bash script และให้บอกว่าฉันต้องการค้นหาร้านอาหารตามชื่อจากไฟล์ด้านบน ถามผู้ใช้สำหรับป้อนชื่อร้านอาหารและควรพิมพ์ข้อมูลเกี่ยวกับร้านอาหารนั้น (5 บรรทัด)

awk '/McDonalds/> /KFC/' example.txt

ฉันรู้ว่าบรรทัดของโค้ดด้านบนจะพิมพ์ทั้งบรรทัดที่ตรงกับรูปแบบ "McDonalds" และ "KFC" แต่จะพิมพ์บรรทัดที่ 1 จากไฟล์ข้อความ แต่ไม่ใช่ข้อมูลที่เหลือเกี่ยวกับร้านอาหารนั้น ฉันจะบอกให้พิมพ์ข้อมูลทั้งหมด (5 บรรทัด) จากเพียงแค่ผู้ใช้ป้อนชื่อร้านอาหารได้อย่างไร

คำตอบ:


11

ด้วย awk คุณสามารถเปลี่ยนตัวแยกเรคคอร์ด โดยค่าเริ่มต้นมันเป็นบรรทัดใหม่ดังนั้นแต่ละบรรทัดของไฟล์คือบันทึก หากคุณตั้งค่าRSตัวแปรเป็นสตริงว่าง awk จะพิจารณาว่าเร็กคอร์ดถูกคั่นด้วยบรรทัดว่าง:

awk -v name="KFC" -v RS="" '$0 ~ "Restaurant: " name' example.txt

ฉันไม่เข้าใจคำถามของคุณ มันค่อนข้างคลุมเครือ มันเป็นการมอบหมายหรือการใช้งานที่คุณไม่ได้รับ?
เกล็นแจ็คแมน

3

การใช้sed:

$ sed -n '/KFC/,/^$/p' file
Restaurant: KFC
City: NYC
State: NY
Address: 123 Madison Square
Phone: 911

$ sed -n '/McDo/,/^$/p' file
Restaurant: McDonalds
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

คำอธิบาย

นี่เป็นsedฟังก์ชั่นพื้นฐานที่คุณสามารถอ้างอิงคำแนะนำที่มีประโยชน์สำหรับ SED

# print section of file between two regular expressions (inclusive)
sed -n '/Iowa/,/Montana/p'             # case sensitive

เพิ่มคำอธิบาย
BMW

แต่ทำไมการแก้ไขที่แนะนำจึงถูกปฏิเสธ ฉันไม่ได้เปลี่ยนคำตอบ ฉันเพิ่งปรับปรุงการจัดรูปแบบ
เดซี่

2
$ awk '$2=="KFC" {print; for(i=1; i<=4; i++) { getline; print}}' example.txt

Restaurant: KFC
City: NYC
State: NY
Address: 123 Madison Square
Phone: 911

คำสั่งดังกล่าวจะได้รับและพิมพ์ 4 บรรทัดต่อเนื่องพร้อมกับบรรทัดปัจจุบันเพราะมันถูกป้อนเข้าไปในวงสำหรับรูปแบบการค้นหา$2=="KFC"จะช่วยให้ได้รับสายเฉพาะจากหลายบรรทัด


0

ทางออกที่เป็นไปได้อื่น ๆ :

awk 'BEGIN{FS="\n";RS="\n\n"}{if($1=="KFC")print $0}' example.txt

{if($1=="KFC")print $0}สามารถข้นเพียง$1 == "KFC"เนื่องจากการดำเนินการเริ่มต้นสำหรับสภาพที่แท้จริงคือการพิมพ์บันทึก
muru

0

ก็เพียงพอที่จะพิมพ์จากบรรทัดที่มีชื่อที่คุณต้องการไปยังบรรทัดสุดท้ายที่มีคำPhone(สมมติว่ารายการทั้งหมดเป็นไปตามรูปแบบเดียวกันและจะมีการPhoneยกเลิกบันทึกเสมอ)

$> awk '/5 guys/,/Phone/' restaurants.txt                                     
Restaurant: 5 guys
City: Atlanta
State: Georgia
Address: 123 Peachtree Rd
Phone: 911
$> awk '/McDonalds/,/Phone/' restaurants.txt                                  
Restaurant: McDonalds 
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

หากเราต้องการทำให้ซับซ้อนสักหน่อยเราสามารถพิมพ์ได้ 5 บรรทัดหลังจากการแข่งขัน:

awk '/McDonalds/{stop=NR+5}; NR<=stop ' restaurants.txt                    

Restaurant: McDonalds 
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

stopตัวแปรจะไม่สามารถตั้งค่าเพื่อNR<=stopจะไม่พิมพ์อะไรจน/McDonalds/{stop=NR+5;}เป็นส่วนหนึ่งจริงชุดตัวแปรและที่จะเกิดขึ้นเมื่อเราพบการแข่งขัน

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