วิธีใช้“:” เป็นตัวคั่นฟิลด์ awk


คำตอบ:


382

"-F" เป็นอาร์กิวเมนต์บรรทัดคำสั่งไม่ใช่ไวยากรณ์ awk ลอง:

 echo "1: " | awk -F  ":" '/1/ {print $1}'

42
คำถามของคนโง่เขลาที่นี่: / 1 / ส่วนคือการบอก awk เพื่อประมวลผลแถวเท่านั้น (หรือบันทึกให้แม่นยำยิ่งขึ้น) ที่มีหมายเลข 1 ใช่ไหม
rantsh

3
@rantsh Awk (pattern){action}ไวยากรณ์ดูเหมือน ถ้าpattern(ส่วนใหญ่เป็นคำสั่งเงื่อนไข) เป็นจริง , actionจะถูกดำเนินการ หากpatternไม่สามารถใช้งานได้trueจะบอกเป็นนัย นี่patternคือ/1/สถานะที่regex 1จับคู่ในระเบียนปัจจุบัน$0
kvantour

62

หากคุณต้องการที่จะทำมันเป็นระบบคุณสามารถใช้FSตัวแปร:

echo "1: " | awk 'BEGIN { FS=":" } /1/ { print $1 }'

โปรดทราบว่าหากคุณเปลี่ยนในลูปหลักแทนที่จะเป็นBEGINลูปจะมีผลต่อการอ่านบรรทัดถัดไปเนื่องจากบรรทัดปัจจุบันได้ถูกแยกออกแล้ว


35

คุณมีหลายวิธีในการตั้งค่า:เป็นตัวคั่น:

awk -F: '{print $1}'

awk -v FS=: '{print $1}'

awk '{print $1}' FS=:

awk 'BEGIN{FS=":"} {print $1}'

ทั้งหมดนี้เทียบเท่ากันและจะส่งคืน1สำหรับอินพุตตัวอย่าง "1: 2: 3":

$ awk -F: '{print $1}' <<< "1:2:3"
1
$ awk -v FS=: '{print $1}' <<< "1:2:3"
1
$ awk '{print $1}' FS=: <<< "1:2:3"
1
$ awk 'BEGIN{FS=":"} {print $1}' <<< "1:2:3"
1

ซึ่งเป็นวิธีที่ต้องการ? ฉันถือว่าตัวอย่างสุดท้ายที่มีBEGINคำสั่งจะถูกต้องที่สุด (สอดคล้องกับawkไวยากรณ์โดยรวม)

1
@ สุ่มเครื่องมือทั้งหมดนั้นใช้ได้ ฉันมักจะใช้BEGINถ้าฉันใช้ไฟล์เพื่อเก็บข้อมูลทั้งหมดในขณะที่-Fมาพร้อมกับพกพาสะดวก
fedorqui 'ดังนั้นหยุดทำร้าย'

1
ต้องบอกว่ามีความแตกต่างเล็กน้อยระหว่างคดีที่สามกับคดีอื่น ๆ ตัวอย่าง: awk 'BEGIN{print split("foo:bar",a)}' FS=":" fileและawk 'BEGIN{FS=":"; print split("foo:bar",a)}' file
kvantour


12

-Fเป็นข้อโต้แย้งกับawkตัวเอง:

$echo "1: " | awk -F":" '/1/ {print $1}'
1

2
ไม่จำเป็นต้องพูดเครื่องหมายจุดคู่
ceving

6

คุณยังสามารถใช้ regex เป็นตัวคั่นฟิลด์ต่อไปนี้จะพิมพ์ "bar" โดยใช้ regex เพื่อตั้งค่าตัวเลข "10" เป็นตัวคั่น

echo "foo 10 bar" | awk -F'[0-9][0-9]' '{print $2}'

4

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

echo "1: " | awk -F: '{print $1}'    
1

echo "1#2" | awk -F# '{print $1}'  
1

4

AWK ทำหน้าที่เป็นตัวแปลข้อความที่ให้ linewise สำหรับเอกสารทั้งหมดและไปตามฟิลด์สำหรับแต่ละบรรทัดดังนั้น $ 1, $ 2 .. $ n เป็นการอ้างอิงไปยังฟิลด์ของแต่ละบรรทัด ($ 1 คือฟิลด์แรก, $ 2 เป็นฟิลด์ที่สองเป็นต้น ... ) คุณสามารถกำหนดตัวคั่นฟิลด์โดยใช้สวิตช์ "-F" ภายใต้บรรทัดคำสั่งหรือภายในวงเล็บสองอันด้วย "FS = ... " พิจารณาคำตอบของ "JUERGEN":

echo "1: " | awk -F  ":" '/1/ {print $1}'

เหนือขอบเขตของเขตข้อมูลถูกตั้งค่าโดย ":" ดังนั้นเราจึงมีสองเขตข้อมูล $ 1 ซึ่งก็คือ "1" และ $ 2 ซึ่งเป็นพื้นที่ว่างหลังจากนั้นมานิพจน์ปกติ "/ 1 /" มาพร้อมกับคำสั่งให้กรองเอาท์พุทฟิลด์แรกเท่านั้น เมื่อล่ามสะดุดที่บรรทัดที่มีนิพจน์ดังกล่าว (ฉันหมายถึง 1) เอาต์พุตของคำสั่ง "echo" คือหนึ่งบรรทัดที่มี "1" ดังนั้นตัวกรองจะทำงาน ...

เมื่อจัดการกับตัวอย่างต่อไปนี้:

echo "1: " | awk '/1/ -F ":" {print $1}'

ไวยากรณ์ยุ่งเหยิงและล่ามเลือกที่จะไม่สนใจส่วน F ":" และสลับไปที่ตัวแยกฟิลด์เริ่มต้นซึ่งเป็นพื้นที่ว่างดังนั้นจึงส่งออก "1:" เป็นฟิลด์แรกและจะไม่มีฟิลด์ที่สอง!

คำตอบของ JUERGEN มีไวยากรณ์ที่ดี ...


3

หรือคุณสามารถใช้:

echo "1: " | awk  '/1/{print $1-":"}' 

นี่คือสมการที่ตลกจริงๆ


1
สิ่งที่ไม่/1/หมายถึง?

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