หากฉันมีคำสั่ง awk
pattern { ... }
และรูปแบบใช้กลุ่มการจับภาพฉันจะเข้าถึงสตริงที่ถูกจับในบล็อกได้อย่างไร
FS
) $field
และเลือกสิ่งที่ต้องการเพื่อให้ตรงกับ การฟอร์แมตอินพุตก็ช่วยได้เช่นกัน
gawk
(เนื่องจากมันใช้gensub
)
หากฉันมีคำสั่ง awk
pattern { ... }
และรูปแบบใช้กลุ่มการจับภาพฉันจะเข้าถึงสตริงที่ถูกจับในบล็อกได้อย่างไร
FS
) $field
และเลือกสิ่งที่ต้องการเพื่อให้ตรงกับ การฟอร์แมตอินพุตก็ช่วยได้เช่นกัน
gawk
(เนื่องจากมันใช้gensub
)
คำตอบ:
นั่นเป็นช่องทางเดินลงหน่วยความจำ ...
ฉันเปลี่ยน awk ด้วย perl เป็นเวลานานแล้ว
เห็นได้ชัดว่าเครื่องมือแสดงออกปกติ AWK ไม่จับกลุ่ม
คุณอาจลองใช้สิ่งต่อไปนี้:
perl -n -e'/test(\d+)/ && print $1'
แฟล็ก -n ทำให้ perl วนซ้ำทุกบรรทัดเหมือน awk
gawk
! awk
= เป็นเครื่องมือที่แตกต่างกันและgawk
ไม่สามารถใช้ได้ตามค่าเริ่มต้นในสถานที่ส่วนใหญ่
ด้วยเพ่งพิศคุณสามารถใช้match
ฟังก์ชั่นในการจับภาพกลุ่มวงเล็บ
gawk 'match($0, pattern, ary) {print ary[1]}'
ตัวอย่าง:
echo "abcdef" | gawk 'match($0, /b(.*)e/, a) {print a[1]}'
cd
เอาท์พุท
สังเกตการใช้งานเพ่งพิศซึ่งใช้งานคุณสมบัติดังกล่าว
สำหรับทางเลือกในแบบพกพาคุณสามารถบรรลุผลที่คล้ายกันด้วยและmatch()
substr
ตัวอย่าง:
echo "abcdef" | awk 'match($0, /b[^e]*/) {print substr($0, RSTART+1, RLENGTH-1)}'
cd
เอาท์พุท
นี่คือสิ่งที่ฉันต้องการตลอดเวลาดังนั้นฉันจึงสร้างฟังก์ชั่นทุบตีสำหรับมัน มันขึ้นอยู่กับคำตอบของเกล็นแจ็คแมน
เพิ่มสิ่งนี้ลงใน. bash_profile เป็นต้น
function regex { gawk 'match($0,/'$1'/, ary) {print ary['${2:-'0'}']}'; }
จับ regex สำหรับแต่ละบรรทัดในไฟล์
$ cat filename | regex '.*'
จับกลุ่มการจับภาพ regex ที่ 1 สำหรับแต่ละบรรทัดในไฟล์
$ cat filename | regex '(.*)' 1
grep -o
อย่างไร?
grep -o
ส่งออกกลุ่มที่ถูกจับได้หรือไม่
grep -o
's
คุณสามารถใช้ GNU awk:
$ cat hta
RewriteCond %{HTTP_HOST} !^www\.mysite\.net$
RewriteRule (.*) http://www.mysite.net/$1 [R=301,L]
$ gawk 'match($0, /.*(http.*?)\$/, m) { print m[1]; }' < hta
http://www.mysite.net/
awk 'match($0, /.*(http.*?)\$/) { print substr($0,RSTART,RLENGTH) }'
RewriteRule (.*) http://www.mysite.net/$
สำหรับฉันซึ่งเป็นมากกว่ากลุ่มย่อย
คุณสามารถจำลองการจับภาพในวานิลลา awk ได้เช่นกันโดยไม่มีส่วนขยาย มันไม่ง่ายแม้ว่า:
ขั้นตอนที่ 1 ใช้ gensub เพื่อล้อมรอบการจับคู่กับอักขระบางตัวที่ไม่ปรากฏในสตริงของคุณ ขั้นตอนที่ 2 ใช้แบ่งกับตัวละคร ขั้นตอนที่ 3 องค์ประกอบอื่น ๆ ในอาร์เรย์ที่แยกออกคือกลุ่มการจับภาพของคุณ
$ echo 'ab cb ad' | awk '{แยก (gensub (/ a ./, SUBSEP "&" SUBSEP, "g", $ 0), หมวก, SUBSEP); ฝาพิมพ์ [2] "|" หมวก [4]; }' AB | โฆษณา
gensub
เป็นgawk
ฟังก์ชั่นเฉพาะ สิ่งใดที่คุณได้รับจาก awk ของคุณถ้าคุณพิมพ์awk --version
-?) โชคดีทุกคน.
echo 'ab cb ad' | awk '{gsub(/a./,SUBSEP"&"SUBSEP);split($0,cap,SUBSEP);print cap[2]"|"cap[4]}'
gawk --posix '{gensub(...)}'
คุณหมายความว่ามันจะบ่นสำหรับ
gensub
ฟังก์ชั่นตัวอย่างของคุณนำไปใช้กับสถานการณ์ที่ จำกัด มาก: รูปแบบทั้งหมดถูกจัดกลุ่ม แต่ก็ไม่สามารถจับคู่สิ่งที่เหมือนkey=(value)
เมื่อฉันต้องการแยกเฉพาะvalue
ส่วน
ฉันต่อสู้เล็กน้อยด้วยฟังก์ชั่นทุบตีที่ห่อคำตอบของ Peter Tillemans แต่นี่คือสิ่งที่ฉันเกิดขึ้น:
ฟังก์ชัน regex {perl -n -e "/ $ 1 / && printf \"% s \ n \ "," '$ 1'}
ฉันพบสิ่งนี้ทำงานได้ดีกว่าฟังก์ชั่นทุบตี awk-based aws สำหรับอาร์กิวเมนต์การแสดงออกปกติต่อไปนี้เพราะฉันไม่ต้องการให้พิมพ์ "ms"
'([0-9]*)ms$'
$1
'([0-9]*)ms$'
- นั่นเป็นข้อโต้แย้ง (และอีกสตริงหนึ่งโต้แย้ง)? และเอาท์พุทจากperl -e
การถูกใส่เข้าไปในprintf
คำสั่งของ bash แล้ว, เพื่อแทนที่%s
, ใช่ไหม? ขอบคุณฉันหวังว่าจะใช้มัน