คำถามเกี่ยวกับ awk


9

ตกลงเนื่องจากเป็นคำถามที่ซับซ้อนฉันจะอธิบายอย่างชัดเจน ฉันได้ไฟล์เนื้อหาที่แสดงด้านล่าง:

$ Cat File1 
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}

ผลลัพธ์ที่ฉันต้องการ

-Cool MNB +  POP ;
-Cool MNB  + POP ;
-Cool MNB  + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD +POP ;

ก่อนอื่นฉันพยายามเอาคอลัมน์สุดท้ายออกจากFile1และพิมพ์ออกมาโดย sed 's/[{}//g' File1 > File3

หลังจากนั้นฉันก็คัดลอกเนื้อหาทั้งหมดของFile1ไปยังใหม่File4

cp File1 File4

หลังจากนั้นฉันจะแทนที่ข้อมูลภายในFile4ด้วยFile3ข้อมูล (หมายถึงข้อมูลที่ไม่มีวงเล็บหนึ่ง " File1คอลัมน์สุดท้ายที่หนึ่ง")

awk 'FNR==NR{a[NR]=$1;next}{$5=a[FNR]}1' File3 File4 >>File5 

ผลลัพธ์ควรเป็นเช่นนี้

ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP TBMKF
ABC Cool Lol POP YUKER
ABC Cool Lol POP EFEFVD

ในที่สุดฉันก็ลอง

awk -F " '{print - $2,$5 +,$4 ";"}‘ File5

แต่ผลลัพธ์ไม่ได้ออกมาตามที่ฉันต้องการเฉพาะข้อมูลที่คล้ายกันของ MNB เท่านั้นที่แสดงรายการทั้งหมดและอื่น ๆ ไม่แสดงขึ้นมา (ไฟล์หนึ่งคอลัมน์ข้อมูลสุดท้าย)


คุณใช้ gnu awk หรือไม่?
123

ฉันไม่แน่ใจว่าคุณหมายถึงอะไร แต่ฉันเป็นเพียงผู้เริ่มต้นใหม่สำหรับการสัมผัส awk นี่เป็นงานที่ฉันต้องทำฉันพยายามอย่างดีที่สุดที่จะค่อยๆก้าวไปทีละขั้นเพื่อทำสิ่งนั้นตามความเข้าใจใน awk
heng960407

1
พิมพ์awk --versionผลลัพธ์คืออะไร
123

2
โปรดเปลี่ยนชื่อของคุณเป็นบางอย่างที่เฉพาะเจาะจงกับปัญหาของคุณ วิธีนี้จะทำให้ง่ายขึ้นสำหรับผู้อื่นที่มีคำถามคล้ายกันในอนาคตเพื่อค้นหา ในขณะนี้ "คำถามเกี่ยวกับ awk" เป็นเรื่องทั่วไปมาก
Tom Fenech

คำตอบ:


16

ฉันไม่รู้ว่าทำไมคุณถึงคัดลอกสิ่งต่าง ๆ ทั้งซ้ายและขวา สิ่งที่ง่ายคือ

awk '{print "-" $2, substr($5,2,length($5)-2), "+", $4, ";"}' File1

ฉันใส่-ในการเริ่มต้นและ;ในตอนท้าย

ในระหว่างที่เราพิมพ์

  • $2 เพราะเราต้องการมันตามที่เป็น
  • สตริงย่อยของ$5ซึ่งเป็นสตริงที่ไม่มีอักขระตัวแรกและตัวสุดท้าย เราข้ามตัวอักษรตัวแรกโดยเริ่มต้นที่ตำแหน่งที่ 2 (awk มักจะแปลกเกี่ยวกับเรื่องนั้น) และปล่อยให้ตัวละครตัวสุดท้ายโดยเลือกสตริงย่อยซึ่งสั้นกว่าสองตัวอักษรกว่าเดิม$5
  • +เพราะเราต้องการมัน
  • แล้ว $4

อย่างไรก็ตามฉันไม่แน่ใจว่าฟังก์ชั่นสตริงเหล่านี้เฉพาะ GNU awk หรือไม่


substr(string, 2)ส่งกลับสตริงย่อยที่เริ่มต้นจากตัวละครที่สองเช่นcut -c2-, tail -n +2, sed '2,$'... มีอะไรแปลก ๆ เกี่ยวกับที่?
Stéphane Chazelas

3
คำสั่งนั้นเป็นมาตรฐานและจะทำงานกับต้นฉบับawkจากยุค 70
Stéphane Chazelas

@ StéphaneChazelas: อ่าฉันรอคุณอยู่แล้ว :-) โดยปกติเราเริ่มนับที่ 0 ซึ่งหมายความว่า index 2 เป็นตำแหน่งที่สาม แต่ที่นี่ตำแหน่งที่สองอยู่ที่ index 2 ขอบคุณที่ชี้แจงคำถาม GNU ที่เหลืออยู่
Bananguin

@Bananguin ใน Unix shell และยูทิลิตี้ดังแสดงในตัวอย่างด้านบนเราเริ่มต้นที่ 1 ไม่ใช่ 0 ข้อยกเว้นที่น่าสังเกตมากที่สุดคือ arrays ของ ksh และ $ {var: offset} (ทั้งคู่ถูกคัดลอกโดย bash) เชลล์อาเรย์อื่น ๆ ทั้งหมดเริ่มต้นที่ 1 ดูเพิ่มเติมมีเหตุผลที่องค์ประกอบแรกของอาร์เรย์ Zsh ถูกจัดทำดัชนีโดย 1 แทนที่จะเป็น 0 หรือไม่?
Stéphane Chazelas

7

ด้วยความใจเย็น

sed '
    s/\S\+\s/-/
    s/\(\S\+\s\)\{2\}{\(\S\+\)}/\2 + \1;/
    ' File1

และการเปลี่ยนแปลงawk

awk -F"[[:blank:]{}]+" '{print "-" $2, $5, "+", $4}' ORS=" ;\n" File1

6

งานTXRง่าย:

$ txr -c '@(repeat)
@a @b @c @d {@e}
@(do (put-line `-@b @e + @d ;`))
@(end)' -
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}
[Ctrl-D][Enter]
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD + POP ;

การใช้มาโคร TXR Lisp awkเพื่อแปลการแก้ปัญหา Awk:

 txr -e '(awk (t (prn `-@[f 1] @{[f 4] [1..-1]} + @[f 3] ;`)))'

เขตข้อมูลอยู่ในfรายการและการจัดทำดัชนีเป็นศูนย์


1
+1 สำหรับรูปที่กระเพื่อมและ crytiest! ภาษานั้นต้องแข่งขันใน pcg (โปรแกรมการเขียนโปรแกรมรหัส)
Archemar

@Archemar TXR ไม่สามารถแข่งขันกอล์ฟได้เป็นอย่างดีเพราะมีภาษาพิเศษที่ออกแบบมาสำหรับสิ่งที่ทำสิ่งต่าง ๆ เช่นกำหนดฟังก์ชั่นให้กับตัวละครแต่ละตัวซึ่งสามารถรวมตัวกันเพื่อให้ได้องค์ประกอบ
Kaz

@Archemar ใส่รายการใน: codegolf.stackexchange.com/questions/68712/output-the-next-kana
Kaz

1
@Kaz มีการสอน TXR ที่ไหนสักแห่งไหม? หน้าคนดูเหมือนจะค่อนข้างใหญ่ มันทำงานอย่างไรเมื่อเทียบกับ awk?
bli

1
@bli GNU Awk เป็นสิ่งที่เร็วกว่าอย่างน้อย 30 เท่าที่เขตข้อมูลพื้นฐานที่แบ่งเป็นไฟล์ขนาดใหญ่กว่ามาโคร TXR awk ซึ่งเป็นโค้ดตีความมากกว่า 220 บรรทัด รวมถึงการวนลูปโดยรวมสำหรับการประมวลผลอินพุตแหล่งลงในระเบียนและฟิลด์
Kaz

3

การใช้ awk นั้นง่ายที่สุดเมื่อ$1,$2,...เขตข้อมูลมีสตริงที่แน่นอนที่คุณต้องการใช้งานอยู่แล้ว ตัวคั่นฟิลด์หากมีอักขระมากกว่าหนึ่งตัวถูกตีความว่าเป็นนิพจน์ทั่วไป เราไม่จำเป็นต้องทำการค้นหาใด ๆ และแทนที่หรือดำเนินการซับสตริงเพื่อกำจัด {curly braces} เราแค่นับมันเป็นส่วนหนึ่งของตัวคั่น

awk -F'[ {}]+' '{printf("-%s %s + %s ;\n", $2, $5, $4)}'

การใช้printfแทนที่จะprintทำให้การจัดรูปแบบสตริงเป็นเรื่องง่ายขึ้น แต่ถ้าคุณต้องการprint "-"$2,$5" + "$4";"แทนที่printf("-%s %s + %s ;\n", $2, $5, $4)นั่นคือตัวเลือก

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