ข้อความนี้หมายถึงการใช้งาน GNU ของ awk ที่รู้จักกันในชื่อ gawk Witch เป็นสิ่งที่ใช้มากที่สุดและมาพร้อมกับการกระจาย Linux / UNIX ที่ทันสมัย
[คู่มือผู้ใช้ GNU AWK] [GNU-AWK] เป็นข้อมูลอ้างอิงสำหรับ ตัวอย่างที่ ฉันใช้กรณีโลกแห่งความจริงที่นำมาจาก [stackoverflow] ของฉัน [ดังนั้น] คำตอบ
AWK เป็นภาษาที่คล้ายกับ Perl ซึ่งมีความสง่างามมากขึ้นเท่านั้น
- อาร์โนลด์ร็อบบินส์
AWK เป็นภาษาการเขียนโปรแกรมที่ออกแบบมาสำหรับการประมวลผลข้อความและโดยทั่วไปจะใช้เป็นเครื่องมือแยกข้อมูลและเครื่องมือการรายงาน มันเป็นคุณสมบัติมาตรฐานของระบบปฏิบัติการที่เหมือน UNIX ส่วนใหญ่
awk Award ...ชื่อของมันมาจากนามสกุลของผู้เขียน - Alfred A Ho, Peter W Einberger และ Brian K Ernighan
awk มาก ...ค้นหาบรรทัดที่มีรูปแบบบางอย่างในไฟล์หรืออินพุตมาตรฐาน
ส่วนใหญ่ใช้สำหรับการสกัดข้อมูลและการรายงานเช่นการสรุปข้อมูลจากผลลัพธ์ของโปรแกรมยูทิลิตี้อื่น ๆ
ไวยากรณ์ C-like
ข้อมูลขับเคลื่อน: มันอธิบายข้อมูลที่คุณต้องการทำงานด้วยแล้วจะทำอะไรเมื่อคุณพบ
pattern { action }
pattern { action }หากโปรแกรม สั้น :
awk ' program ' input-file1 input-file2หมายเหตุ: ระวังปัญหาการอ้างถึงเชลล์ 1 .
cmd | awk ' program ' หมายเหตุ: pipe เปลี่ยนเส้นทางเอาต์พุตของคำสั่ง ซ้ายมือ ( cmd ) ไปยัง อินพุต ของคำสั่ง awk 2
เมื่อรหัส ยาว มักจะสะดวกกว่าที่จะใส่ไว้ในไฟล์และเรียกใช้ด้วยคำสั่งเช่นนี้:
awk -f program-file input-file1 input-file2
cmd | awk -f program-file หรือเพียงแค่ทำให้มันทำงานได้เหมือน shebang :
#! /bin/awk -f
BEGIN { print " hello world!! " } -F fs ตั้งค่าตัวแปร FS เป็น fs
-v var=val ตั้งค่าตัวแปร var เป็นค่า val ก่อนที่จะดำเนินการโปรแกรมเริ่มต้น
หมายเหตุ : สามารถใช้งานได้มากกว่าหนึ่งครั้ง ตั้งค่า ตัวแปรอื่นในแต่ละครั้ง
รูปแบบพิเศษหรือบล็อกเหล่านี้จัดหา การเริ่มต้น และการ ล้าง ข้อมูลสำหรับโปรแกรม awk
BEGIN{
// initialize variables
}
{
/pattern/ { action }
}
END{
// cleanup
}BEGIN ก่อนที่จะอ่านระเบียนอินพุตครั้งแรก END หลังจากการป้อนข้อมูลทั้งหมดจะถูกใช้ไป
$ echo " hello " | awk ' BEGIN{print "BEGIN";f=1}
{print $f}
END{print "END"} '
BEGIN
hello
ENDgrepping ถ้าคุณมี awk ?? $ cat lorem_ipsum.dat
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Maecenas pellentesque erat vel tortor consectetur condimentum.
Nunc enim orci, euismod id nisi eget, interdum cursus ex.
Curabitur a dapibus tellus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aliquam interdum mauris volutpat nisl placerat, et facilisis.$ grep dolor lorem_ipsum.dat
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.$ awk ' /dolor/ ' lorem_ipsum.dat
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.หมายเหตุ: หากการกระทำไม่ได้รับการ ดำเนินการเริ่มต้น คือการพิมพ์บันทึกที่ตรงกับรูปแบบที่กำหนด
แต่ ... เราจะค้นหาคำ แรก และคำ สุดท้าย ของแต่ละบรรทัดได้อย่างไร?
แน่นอนว่า grep สามารถทำได้ แต่ต้องการสองขั้นตอน:
$ grep -Eo ' ^[^ ]+ ' lorem_ipsum.dat
Lorem
Maecenas
Nunc
Curabitur
Lorem
Aliquam$ grep -Eo ' [^ ]+$ ' lorem_ipsum.dat
elit.
condimentum.
ex.
tellus.
elit.
ultrices. มาดูกันว่า awk ที่นี่:
$ awk ' {print $1,$NF} ' lorem_ipsum.dat
Lorem elit.
Maecenas condimentum.
Nunc ex.
Curabitur tellus.
Lorem elit.
Aliquam ultrices. awk แบ่งอินพุตสำหรับโปรแกรมของคุณออกเป็น ระเบียน และ ฟิลด์
บันทึก จะถูกคั่นด้วยอักขระที่เรียกว่า เร็กคอร์ดคั่น RS โดยค่าเริ่มต้น ตัวคั่นบันทึกคืออักขระ Unix Newline n
นี่คือเหตุผลที่บันทึก เป็นค่าเริ่ม ต้นบรรทัดเดียว
นอกจากนี้ awk ยังมี ตัวคั่นเร็กคอร์ด ORS Output เพื่อควบคุมวิธีการบันทึกบันทึกไปยัง stdout
RS และ ORS ควรอยู่ใน เครื่องหมายคำพูด ซึ่งระบุ ค่าคง ที่สตริง
หากต้องการใช้อักขระที่แตกต่างกันหรือ regex เพียงกำหนดให้กับตัวแปร RS หรือ / และ ORS :
BEGIN ก่อนที่อินพุตจะถูกประมวลผลเพื่อให้บันทึกครั้งแรกถูกอ่านด้วยตัวคั่นที่เหมาะสมตัวอย่าง:
$ awk ' BEGIN{RS=" *, *";ORS="<<<---n"}
{print $0} ' lorem_ipsum.dat
Lorem ipsum dolor sit amet <<< ---
consectetur adipiscing elit.
Maecenas pellentesque erat vel tortor consectetur condimentum.
Nunc enim orci <<< ---
euismod id nisi eget <<< ---
interdum cursus ex.
Curabitur a dapibus tellus.
Lorem ipsum dolor sit amet <<< ---
consectetur adipiscing elit.
Aliquam interdum mauris volutpat nisl placerat <<< ---
et facilisis neque ultrices.
<<< --- $ awk ' {print $0} ' RS= " *, * " ORS= " <<<---n " lorem_ipsum.dat
Lorem ipsum dolor sit amet <<< ---
consectetur adipiscing elit.
Maecenas pellentesque erat vel tortor consectetur condimentum.
Nunc enim orci <<< ---
euismod id nisi eget <<< ---
interdum cursus ex.
Curabitur a dapibus tellus.
Lorem ipsum dolor sit amet <<< ---
consectetur adipiscing elit.
Aliquam interdum mauris volutpat nisl placerat <<< ---
et facilisis neque ultrices.
<<< --- บันทึก awk จะถูกแยกวิเคราะห์โดยอัตโนมัติหรือแยกออกเป็น ชิ้น ที่เรียกว่า ฟิลด์
โดยค่าเริ่มต้นฟิลด์จะถูกคั่นด้วย ช่องว่าง (สตริงใด ๆ ของช่องว่างหนึ่งช่องหรือมากกว่าใหม่) เช่นคำในบรรทัด
ในการอ้างถึงฟิลด์ในโปรแกรม awk คุณใช้เครื่องหมายดอลลาร์ $ ตามด้วยจำนวนฟิลด์ที่คุณต้องการ
ดังนั้น $1 หมายถึงฟิลด์แรก $2 ถึงที่สองและอื่น ๆ
สำคัญ : $0 หมายถึงบันทึกอินพุตทั้งหมด
$ awk ' {print $3} ' lorem_ipsum.dat
dolor
erat
orci,
dapibus
dolor
mauris NF เป็นตัวแปรที่กำหนดไว้ล่วงหน้าค่าคือ จำนวนฟิลด์ในบันทึกปัจจุบัน ดังนั้น $NF จะเป็นฟิลด์สุดท้ายของบันทึกเสมอ
$ awk ' {print NF} ' lorem_ipsum.dat
8
7
10
4
8
10เทียบกับ
$ awk ' {print $NF} ' lorem_ipsum.dat
elit.
condimentum.
ex.
tellus.
elit.
facilisis. FS ถือมูลค่าของ ตัวคั่นฟิลด์ ค่านี้เป็นสตริงตัวละครเดี่ยวหรือ regex ที่ตรงกับการแยกระหว่างฟิลด์ในบันทึกอินพุต
ค่าเริ่มต้นคือ " " สตริงที่ประกอบด้วยพื้นที่เดียว เป็นข้อยกเว้นพิเศษค่านี้หมายความว่าลำดับของ ช่องว่าง แท็บ และ/หรือ newLines ใด ๆ เป็นตัวคั่นเดี่ยว
ในแบบเดียวกับ ORS เรามีตัวแปร OFS เพื่อจัดการวิธีการส่งฟิลด์ของเราไปยังสตรีมเอาท์พุท
$ cat /etc/group
nobody: * :-2:
nogroup: * :-1:
wheel: * :0:root
daemon: * :1:root
kmem: * :2:root
sys: * :3:root
tty: * :4:root$ awk ' !/^(_|#)/&&$1=$1 ' FS= " : " OFS= " <-> " /etc/group
nobody < - > * < - > - 2< - >
nogroup < - > * < - > - 1< - >
wheel < - > * < - > 0 < - > root
daemon < - > * < - > 1 < - > root
kmem < - > * < - > 2 < - > root
sys < - > * < - > 3 < - > root
tty < - > * < - > 4 < - > root หมายเหตุ : อืมม ... $1=$1 ???? 3
การเก็บ บันทึก และ ฟิลด์ อยู่ในใจขณะนี้พร้อมที่จะเข้าใจรหัสก่อนหน้าของเรา:
$ awk ' {print $1,$NF} ' lorem_ipsum.dat
Lorem elit.
Maecenas condimentum.
Nunc ex.
Curabitur tellus.
Lorem elit.
Aliquam ultrices.นี่คือสองตัวแปรในตัวที่มีประโยชน์ในตัว:
NR : จำนวนการบันทึกอินพุต awk ได้ประมวลผลตั้งแต่เริ่มต้นการดำเนินการของโปรแกรม
FNR : หมายเลขบันทึกปัจจุบันในไฟล์ปัจจุบัน awk จะรีเซ็ต FNR เป็น ศูนย์ ทุกครั้งที่เริ่มไฟล์อินพุตใหม่
$ cat n1.dat
one
two$ cat n2.dat
three
four$ awk ' {print NR,FNR,$0} ' n1.dat n2.dat
1 1 one
2 2 two
3 1 three
4 2 fourสตริงรูปแบบคล้ายกับที่อยู่ใน ISO C มาก
ไวยากรณ์:
printf format, item1, item2, …
$ awk ' {printf "%20s <-> %sn",$1,$NF} ' lorem_ipsum.dat
Lorem < - > elit.
Maecenas < - > condimentum.
Nunc < - > ex.
Curabitur < - > tellus.
Lorem < - > elit.
Aliquam < - > ultrices. เอาต์พุตจาก print และ printf ถูกนำไปยัง เอาต์พุตมาตรฐาน โดยค่าเริ่มต้น แต่เราสามารถใช้การเปลี่ยนเส้นทางเพื่อเปลี่ยนปลายทาง
การเปลี่ยนเส้นทางใน awk นั้นเขียนขึ้นเช่นการเปลี่ยนเส้นทางในคำสั่ง เชลล์ ยกเว้นว่าพวกเขาถูกเขียนไว้ในโปรแกรม awk
$ awk ' BEGIN{print "hello">"hello.dat"} ' $ awk ' BEGIN{print "world!">>"hello.dat"} ' $ cat hello.dat
hello
world !นอกจากนี้ยังเป็นไปได้ที่จะส่งผลลัพธ์ไปยังโปรแกรมอื่นผ่าน ท่อ :
$ awk ' BEGIN{sh="/bin/sh";print "date"|sh;close(sh)} '
dom nov 13 18:36:25 CET 2016 [สตรีม] สามารถชี้ไปที่ stdin , stdout และ stderr
ตัวอย่างเช่นเราสามารถเขียนข้อความแสดงข้อผิดพลาดไปยัง stderr เช่นนี้:
$ awk ' BEGIN{print "Serious error detected!" > "/dev/stderr"} '
Serious error detected ! ใน AWK อาร์เรย์มี การเชื่อมโยงกัน แต่ละชุดคือชุดของ คู่ ดัชนี - ค่า ซึ่งหมายเลขหรือสตริงใด ๆ สามารถเป็นดัชนี
ไม่จำเป็นต้องมีการประกาศ สามารถเพิ่มคู่ใหม่ได้ตลอดเวลา
| ดัชนี | ค่า |
|---|---|
| "Perro" | "สุนัข" |
| "Gato" | "แมว" |
| "uno" | "หนึ่ง" |
| 1 | "หนึ่ง" |
| 2 | "สอง" |
เพื่ออ้างอิงอาร์เรย์:
array[index-expression]
เพื่อกำหนดค่า:
array[index-expression] = value
เพื่อตรวจสอบว่ามีการจัดทำดัชนีคีย์หรือไม่:
indx in array
เพื่อวนซ้ำ:
for (var in array) {
var, array[var]
}การใช้ค่าตัวเลขเป็นดัชนีและรักษาคำสั่งซื้อ:
for (i = 1 ; i < = max_index ; i++) {
print array[i]
}ตัวอย่างที่สมบูรณ์:
$ cat dict.dat
uno one
dos two
tres three
cuatro fourawk ' {dict[$1]=$2}
END{if ("uno" in dict)
print "Yes we have uno in dict!"
if (!("cinco" in dict))
print "No , cinco is not in dict!"
for (esp in dict){
print esp, "->" ,dict[esp]
}
} ' dict.datให้คุณ:
Yes we have uno in dict !
No , cinco is not in dict !
uno - > one
dos - > two
tres - > three
cuatro - > four gawk ไม่ได้เรียงลำดับอาร์เรย์ตามค่าเริ่มต้น:
awk ' BEGIN{
a[4]="four"
a[1]="one"
a[3]="three"
a[2]="two"
a[0]="zero"
exit
}
END{for (idx in a){
print idx, a[idx]
}
} ' 4 four
0 zero
1 one
2 two
3 threeแต่คุณสามารถใช้ประโยชน์จาก [procinfo] สำหรับการเรียงลำดับ:
awk ' BEGIN{
PROCINFO["sorted_in"] = "@ind_num_asc"
a[4]="four"
a[1]="one"
a[3]="three"
a[2]="two"
a[0]="zero"
exit
}
END{for (idx in a){
print idx, a[idx]
}
} ' 0 zero
1 one
2 two
3 three
4 four gensub(regexp, replacement, how [, target]) : เป็นฟังก์ชั่นขั้นสูงที่สุดสำหรับการเปลี่ยนสตริง
และทางเลือกที่ง่ายกว่าของพวกเขา:
gsub(regexp, replacement [, target])
sub(regexp, replacement [, target])
มีไฟล์นี้:
$ cat lorem.dat
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Maecenas pellentesque erat vel tortor consectetur condimentum.
Nunc enim orci, euismod id nisi eget, interdum cursus ex.
Curabitur a dapibus tellus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aliquam interdum mauris volutpat nisl placerat, et facilisis.เราจะสลับตำแหน่งของคำที่วางไว้ที่ ด้านซ้าย และ ด้านขวา ของแต่ละเครื่องหมายจุลภาค
$ awk ' {print gensub(/([^ ]+)( *, *)([^ ]+)/,
"\3\2\1", "g")} ' lorem.dat
Lorem ipsum dolor sit consectetur, amet adipiscing elit.
Maecenas pellentesque erat vel tortor consectetur condimentum.
Nunc enim euismod, orci id nisi interdum, eget cursus ex.
Curabitur a dapibus tellus.
Lorem ipsum dolor sit consectetur, amet adipiscing elit.
Aliquam interdum mauris volutpat nisl et, placerat facilisis. การใช้ gensub เราจับ สามกลุ่ม จากนั้นเราเปลี่ยนคำสั่งซื้อ
เพื่อแสดงให้เห็นถึงการกระทำที่ง่ายขึ้นลองเปลี่ยน จุด สำหรับ เครื่องหมายจุลภาค :
awk ' $0=gensub(/./, ",", "g") ' lorem.dat
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
Maecenas pellentesque erat vel tortor consectetur condimentum,
Nunc enim orci, euismod id nisi eget, interdum cursus ex,
Curabitur a dapibus tellus,
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
Aliquam interdum mauris volutpat nisl placerat, et facilisis, การใช้ทางเลือก gsub :
awk ' gsub(/./, ",") ' lorem.dat
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
Maecenas pellentesque erat vel tortor consectetur condimentum,
Nunc enim orci, euismod id nisi eget, interdum cursus ex,
Curabitur a dapibus tellus,
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
Aliquam interdum mauris volutpat nisl placerat, et facilisis,ตัวเลือกนี้ดูเหมือนจะดีกว่าเมื่อไม่จำเป็นต้องมี การจับกลุ่ม
ฟังก์ชั่นที่น่าสนใจอื่น ๆ คือ index และ substr
index(in, find)
substr(string, start [, length ])
ใช้งานได้เช่นนี้:
$ awk ' BEGIN{t="hello-world";print index(t, "-")} '
6$ awk ' BEGIN{t="hello-world";print substr(t,index(t, "-")+1)} '
world ฟังก์ชั่น split ใช้เพื่อสร้างอาร์เรย์จากสตริงที่หารด้วย ตัวคั่นถ่าน มันจะส่งคืนจำนวนองค์ประกอบของอาร์เรย์ที่สร้างขึ้น
split(string, array [, fieldsep [, seps ] ])
$ cat passwd
jd001:x:1032:666:Javier Diaz:/home/jd001:/bin/rbash
ag002:x:8050:668:Alejandro Gonzalez:/home/ag002:/bin/rbash
jp003:x:1000:666:Jose Perez:/home/jp003:/bin/bash
ms004:x:8051:668:Maria Saenz:/home/ms004:/bin/rbash
rc005:x:6550:668:Rosa Camacho:/home/rc005:/bin/rbash$ awk ' n=split($0, a, ":"){print n, a[n]} ' passwd
7 /bin/rbash
7 /bin/rbash
7 /bin/bash
7 /bin/rbash
7 /bin/rbashหมายเหตุ : สิ่งนี้สามารถทำได้ในวิธีที่ง่ายกว่ามาก:
$ awk ' {print NF,$NF} ' FS= ' : ' passwd
7 /bin/rbash
7 /bin/rbash
7 /bin/bash
7 /bin/rbash
7 /bin/rbashเขียนฟังก์ชั่นที่กำหนดเองค่อนข้างง่าย:
awk ' function test(m)
{
printf "This is a test func, parameter: %sn", m
}
BEGIN{test("param")} 'ให้เรา:
This is a test func, parameter: param นอกจากนี้เรายังสามารถคืนนิพจน์โดยใช้คำสั่ง return :
awk ' function test(m)
{
return sprintf("This is a test func, parameter: %s", m)
}
BEGIN{print test("param")} 'การแยกวิเคราะห์โดยพารามิเตอร์เป็นวิธีเดียวที่จะสร้างตัวแปรท้องถิ่นภายในฟังก์ชั่น
ค่าสเกลาร์จะถูกส่งผ่านตามค่าและอาร์เรย์โดยอ้างอิงดังนั้นการเปลี่ยนแปลงใด ๆ ที่เกิดขึ้นกับอาร์เรย์ภายในฟังก์ชั่นจะสะท้อนให้เห็นในขอบเขตทั่วโลก:
awk ' function test(m)
{
m[0] = "new"
}
BEGIN{m[0]=1
test(m)
exit
}
END{print m[0]} 'เอาต์พุต:
newความท้าทายของเรา :
01. คำพูดสุดท้ายของบันทึก
02. แทนที่บันทึก
03. วางอัฒภาคในตอนท้ายของแต่ละบันทึก
04. วางเครื่องหมายจุลภาคระหว่างทุกคำ
05. ทั้งหมดเข้าด้วยกัน?
06. เปลี่ยนเส้นทางบันทึกคี่ไปยังไฟล์และแม้แต่ไฟล์อื่น
07. ให้ไฟล์รหัสผ่านรับฟิลด์ที่หายไป
08. การแลกเปลี่ยนฟิลด์
09. Traceroute Hacking
10. ลูก ๆ ของฉันอยู่ที่ไหน?
11. การรวมข้อมูล
12. บันทึกระหว่างสองรูปแบบ
13. การเปลี่ยนแปลงภาคสนาม
14. บันทึกไปยังคอลัมน์
15. การประมวลผลไฟล์ FASTA
16. การรายงานที่ซับซ้อน
17. ผู้เข้าร่วมไฟล์
18. Passwd และกลุ่ม
19. การเชื่อมต่อผู้ใช้
20. ค่าเฉลี่ยโหลดทั้งหมดของเวลารับ
มีไฟล์ ต้นฉบับ นี้:
$ cat lorem.dat
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Maecenas pellentesque erat vel tortor consectetur condimentum.
Nunc enim orci, euismod id nisi eget, interdum cursus ex.
Curabitur a dapibus tellus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aliquam interdum mauris volutpat nisl placerat, et facilisis.$ awk ' {print $(NF-1)} ' lorem.dat
adipiscing
consectetur
cursus
dapibus
adipiscing
neque ไม่มากเกินไปที่จะอธิบายที่นี่ NF เก็บ จำนวนฟิลด์ ในบันทึกปัจจุบันดังนั้น NF-1 ชี้ไปที่ฟิลด์ก่อนและ $(NF-1) จะเป็นค่าของมัน
งานของเราการทดแทนบันทึกไฟล์บรรทัดที่สามจะต้องกลายเป็น:
This not latin
ไม่มีอะไรง่ายไปกว่านี้เพียงแค่เล่นรอบ NR ( จำนวนบันทึก )
รหัส:
$ awk ' NR==3{print "This is not latin";next}{print} ' lorem.dat
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Maecenas pellentesque erat vel tortor consectetur condimentum.
This is not latin
Curabitur a dapibus tellus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aliquam interdum mauris volutpat nisl placerat, et facilisis. ทางเลือกอื่นเพื่อหลีกเลี่ยงคำสั่ง next : กำหนดบรรทัดใหม่ให้กับระเบียนที่สมบูรณ์ $0
ตัวอย่าง:
$ awk ' NR==3{$0="This is not latin"}1 ' lorem.dat
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Maecenas pellentesque erat vel tortor consectetur condimentum.
This is not latin
Curabitur a dapibus tellus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aliquam interdum mauris volutpat nisl placerat, et facilisis.$ awk ' 1 ' ORS= " ;n " lorem.dat
Lorem ipsum dolor sit amet, consectetur adipiscing elit. ;
Maecenas pellentesque erat vel tortor consectetur condimentum. ;
Nunc enim orci, euismod id nisi eget, interdum cursus ex. ;
Curabitur a dapibus tellus. ;
Lorem ipsum dolor sit amet, consectetur adipiscing elit. ;
Aliquam interdum mauris volutpat nisl placerat, et facilisis neque ultrices. ; เนื่องจากค่าเริ่มต้น RS คือ Unix Break Line n เราเพียงแค่ต้อง นำหน้า เครื่องหมายอัฒภาคไปยังตัวคั่นเร็กคอร์ดเอาต์พุต OFS
1 ล่ะ? 4
$ awk ' {$1=$1}1 ' OFS= ' , ' lorem.dat
Lorem,ipsum,dolor,sit,amet,,consectetur,adipiscing,elit.
Maecenas,pellentesque,erat,vel,tortor,consectetur,condimentum.
Nunc,enim,orci,,euismod,id,nisi,eget,,interdum,cursus,ex.
Curabitur,a,dapibus,tellus.
Lorem,ipsum,dolor,sit,amet,,consectetur,adipiscing,elit.
Aliquam,interdum,mauris,volutpat,nisl,placerat,,et,facilisis,neque,ultrices. ส่วนที่สำคัญที่สุดของรหัสนี้คือวิธีที่จะบังคับให้มีการสร้างสถิติใหม่ด้วย $1=$1 สำหรับค่าปัจจุบันของ OFS
$ awk ' {$1=$1}1 ' OFS= ' , ' ORS= ' ;n ' lorem.dat
Lorem,ipsum,dolor,sit,amet,,consectetur,adipiscing,elit. ;
Maecenas,pellentesque,erat,vel,tortor,consectetur,condimentum. ;
Nunc,enim,orci,,euismod,id,nisi,eget,,interdum,cursus,ex. ;
Curabitur,a,dapibus,tellus. ;
Lorem,ipsum,dolor,sit,amet,,consectetur,adipiscing,elit. ;
Aliquam,interdum,mauris,volutpat,nisl,placerat,,et,facilisis,neque,ultrices. ; เช่น เดียว กับการเล่นกับ vars เอาท์พุท: OFS และ ORS
เริ่มต้นด้วยวิธีแก้ปัญหาสุดท้าย:
$ awk ' NR%2{print > "even.dat";next}
{print > "odd.dat"} ' lorem.dat$ cat even.dat
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Nunc enim orci, euismod id nisi eget, interdum cursus ex.
Lorem ipsum dolor sit amet, consectetur adipiscing elit$ cat odd.dat
Maecenas pellentesque erat vel tortor consectetur condimentum.
Curabitur a dapibus tellus.
Aliquam interdum mauris volutpat nisl placerat, et facilisis. ฟังก์ชั่น [modulo] ( % ) พบ ส่วนที่เหลือหลังจากการแบ่งสำหรับหมายเลขบันทึกปัจจุบัน NR หารด้วยสอง:
$ awk ' {print NR%2} ' lorem.dat
1
0
1
0
1
0 เท่าที่เรายังอยู่ตอนนี้ใน awk 1 เป็น จริง และ 0 เท็จ เราเปลี่ยนเส้นทางเอาต์พุตของเราประเมินความจริงนี้
next ต้องการความสนใจเป็นพิเศษมัน บังคับให้ awk หยุดกระบวนการบันทึกปัจจุบัน ทันที และส่งผ่านไปยังอีก
ด้วยวิธีนี้เราจะหลีกเลี่ยงเงื่อนไขสองเท่าที่จะเป็นเช่นนี้:
awk ' NR % 2{print > "even.dat"}
!NR % 2{print > "odd.dat"} ' lorem.dat$ cat /etc/passwd
jd001:x:1032:666:Javier Diaz::/bin/rbash
ag002:x:8050:668:Alejandro Gonzalez::/bin/rbash
jp003:x:1000:666:Jose Perez::/bin/bash
ms004:x:8051:668:Maria Saenz::/bin/rbash
rc005:x:6550:668:Rosa Camacho::/bin/rbash สมมติ "/home/" ไดเรกทอรี โฮม
$ awk ' $6="/home/"$1 ' FS= ' : ' OFS= ' : ' /etc/passwd
jd001:x:1032:666:Javier Diaz:/home/jd001:/bin/rbash
ag002:x:8050:668:Alejandro Gonzalez:/home/ag002:/bin/rbash
jp003:x:1000:666:Jose Perez:/home/jp003:/bin/bash
ms004:x:8051:668:Maria Saenz:/home/ms004:/bin/rbash
rc005:x:6550:668:Rosa Camacho:/home/rc005:/bin/rbashขั้นตอนแรกของเราควรพิจารณาตัวคั่นฟิลด์ลำไส้ใหญ่สำหรับอินพุตและเอาต์พุต
จากนั้นเราต้องหาตำแหน่งฟิลด์โมฆะ 6 สำหรับตัวอย่างนี้
ในที่สุดเราเขียนค่าที่ต้องการโดยใช้สตริงที่กำหนดและการเข้าสู่ระบบของผู้ใช้ที่เก็บไว้ในฟิลด์แรก
print เนื่องจากค่าการส่งคืนการมอบหมาย $6 จะเป็น จริง และการดำเนินการเริ่มต้น awk คือการพิมพ์บันทึกที่ได้รับผลกระทบ
เป้าหมายของเรา: ฟิลด์สุดท้ายควรกลายเป็นครั้งแรกและครั้งแรก
รหัสสุดท้าย:
$ awk -F : ' {last=$1;$1=$NF;$NF=last}1 ' FS= " : " OFS= ' : ' /etc/passwd
/bin/rbash:x:1032:666:Javier Diaz:/home/jd001:jd001
/bin/rbash:x:8050:668:Alejandro Gonzalez:/home/ag002:ag002
/bin/bash:x:1000:666:Jose Perez:/home/jp003:jp003
/bin/rbash:x:8051:668:Maria Saenz:/home/ms004:ms004
/bin/rbash:x:6550:668:Rosa Camacho:/home/rc005:rc005 เรากำลังเล่นกับตัวแปรระดับ กลาง ที่ใช้ในการจัดเก็บค่าฟิลด์แรกเราสลับค่าของมันด้วยค่าสุดท้ายในที่สุดเราก็กำหนดตัวแปร last เป็น $NF ( $NF=last )
มีเอาต์พุตนี้:
$ traceroute -q 1 google.com 2> /dev/null
1 hitronhub.home (192.168.1.1) 5.578 ms
2 217.217.0.1.dyn.user.ono.com (217.217.0.1) 9.732 ms
3 10.127.54.181 (10.127.54.181) 10.198 ms
4 62.42.228.62.static.user.ono.com (62.42.228.62) 35.519 ms
5 72.14.235.20 (72.14.235.20) 26.003 ms
6 216.239.50.133 (216.239.50.133) 25.678 ms
7 mad01s24-in-f14.1e100.net (216.58.211.238) 25.019 msเราจำเป็นต้องคำนวณแพคเกจ การเดินทาง เวลาทั้งหมด
$ traceroute -q 1 google.com 2> /dev/null |
awk ' {total+=$(NF-1)}
END{print "Total ms: "total} '
Total ms: 153.424เนื่องจากไม่ได้ระบุเงื่อนไขการดำเนินการจะดำเนินการ สำหรับบันทึกทั้งหมด
total+=$(NF-1) : ตัวแปร total ใช้เพื่อ สะสม ค่าของแต่ละ บันทึกการบันทึก penultimate $(NF-1)
ในที่สุดเราใช้กฎ END เพื่อแสดงค่า total สุดท้าย
งานของเรา: รับกระบวนการ ขึ้นอยู่กับ shell ของเรา
$ echo $$
51026สิ่งแรก : เปิดกระบวนการพื้นหลัง
$ sleep 10 & sleep 15 & sleep 20 &
[1] 86751
[2] 86752
[3] 86753 การใช้ ยูทิลิตี้ ps awk จะมองหาฟิลด์ที่สามที่เรียกว่า PPID
หมายเหตุ : เราใช้ -v เพื่อตั้งค่า PPID VAR ก่อนที่จะดำเนินการโปรแกรมเริ่มต้น
$ ps -ef | awk -v ppid= $$ ' $3==ppid '
501 86751 51026 0 7:57PM ttys001 0:00.00 sleep 10
501 86752 51026 0 7:57PM ttys001 0:00.00 sleep 15
501 86753 51026 0 7:57PM ttys001 0:00.00 sleep 20
0 86754 51026 0 7:57PM ttys001 0:00.00 ps -ef
501 86755 51026 0 7:57PM ttys001 0:00.00 awk $3 ==51026เราแค่ต้องการ การนอนหลับ :
$ ps -ef | awk -v ppid= $$ ' $3 == ppid && /slee[p]/
{print $2" -> "$5} '
86751 - > 7:57PM
86752 - > 7:57PM
86753 - > 7:57PM โซลูชันต้องการเงื่อนไขใหม่ในการเพิ่ม: ค้นหารูปแบบ การนอนหลับใน บันทึก /slee[p]/
การกระทำ ที่ทริกเกอร์ จะพิมพ์ฟิลด์ที่สอง $2 พร้อมย่อมาจาก PID และห้า $5 , การประทับเวลา
มีไฟล์นี้:
$ cat ips.dat
IP BYTES
81.220.49.127 328
81.220.49.127 328
81.220.49.127 329
81.220.49.127 367
81.220.49.127 5302
81.226.10.238 328
81.227.128.93 84700 งานของเราคือการคำนวณจำนวน ไบต์ ต่อ IP ที่ประมวลผล
$ awk ' NR>1{ips[$1]+=$2}
END{for (ip in ips){print ip, ips[ip]}} ' ips.dat
81.220.49.127 6654
81.227.128.93 84700
81.226.10.238 328สิ่งต่าง ๆ ที่นี่เพื่ออธิบาย
NR>1{ips[$1]+=$2} : การกระทำ ips[$1]+=$2 จะดำเนินการเฉพาะเมื่อหมายเลขระเบียนปัจจุบันมากกว่าหนึ่ง NR>1 สิ่งนี้จำเป็นเพื่อหลีกเลี่ยงส่วนหัว
ips เป็นอาร์เรย์ที่จัดทำดัชนีโดย ค่า IP (ฟิลด์ $1 ) สำหรับแต่ละคีย์เราจะสะสมในค่าของฟิลด์ที่สอง
สังเกต ข้อเท็จจริงที่สำคัญ หากไม่มีคีย์อยู่ในอาร์เรย์ awk จะเพิ่มองค์ประกอบใหม่ให้กับ โครงสร้าง มิฉะนั้นจะอัปเดตค่าก่อนหน้านี้ที่ชี้ไปที่คีย์นั้น (เช่นในตัวอย่างของเรา)
กฎ END ใช้เพื่อทำซ้ำอาร์เรย์ตามดัชนีและค่า
รหัสนี้สามารถเขียนใหม่ ในลักษณะที่แตกต่างกันอย่างสมบูรณ์เพื่อหลีกเลี่ยงการใช้อาร์เรย์และรักษาคำสั่งซื้อที่ใช้ประโยชน์จากไฟล์ IPS ที่เรียงลำดับ:
awk ' NR==1{next}
lip && lip != $1{print lip,sum;sum=0}
{sum+=$2;lip=$1}
END{print lip,sum} ' ips.dat
81.220.49.127 6654
81.226.10.238 328
81.227.128.93 84700 NR==1{next} : บายพาสส่วนหัว
lip && lip != $1{print lip,sum;sum=0} : ที่นี่เราใช้ VAR ชื่อ lip ( Last-IP ) lip && lip != $1 เมื่อ lip ไม่เป็นโมฆะ และ ค่าไม่เท่ากับฟิลด์แรก (ที่ถือ IP ปัจจุบัน) การกระทำที่ทริกเกอร์จะพิมพ์ lip และ sum จำนวนเงินทั้งหมดของไบต์สำหรับ IP สุดท้าย จากนั้นเราเริ่มต้นมัน sum=0
เคล็ดลับ มีความชัดเจน ทุกครั้งที่ IP ( $1 ) เปลี่ยนแปลง เราแสดงสถิติของหนึ่งก่อนหน้า
{sum+=$2;lip=$1} : เพื่ออัปเดต Sum Bytes Counter sum+=$2 และกำหนด IP ปัจจุบันให้กับ lip : lip=$1 มันเป็นขั้นตอนสุดท้ายของการประมวลผลบันทึกของเรา
บล็อก END ใช้เพื่อพิมพ์ ค่าที่รอดำเนินการ
รหัสนี้รักษาคำสั่งซื้อ แต่ ในความคิดของฉัน สิ่งนี้มาจากค่าใช้จ่ายของความซับซ้อนที่เพิ่มขึ้นอย่างมีนัยสำคัญ
งานของเราคือสองแยกเส้น ระหว่าง และ OUTPUT และ END
$ cat pat.dat
test -3
test -2
test -1
OUTPUT
top 2
bottom 1
left 0
right 0
page 66
END
test 1
test 2
test 3 นี่เป็น ตัวอย่างคลาสสิก ที่ใช้เพื่อ แสดงให้เห็นว่า การจับคู่รูปแบบ ทำงานอย่างไรใน awk และการกระทำที่เกี่ยวข้องซึ่งฉันทุ่มเท [โพสต์] ที่สมบูรณ์
$ awk ' /END/{flag=0}flag;/OUTPUT/{flag=1} ' pat.dat
top 2
bottom 1
left 0
right 0
page 66 มันขึ้นอยู่กับค่าตัวแปร flag มันจะเป็น จริง ( 1 ) เมื่อพบ OUTPUT รูปแบบเริ่มต้นและ เท็จ ( 0 ) เมื่อถึง แท็ก END
เพื่อหลีกเลี่ยงขั้นตอนเพิ่มเติม คำสั่งการดำเนินการมีความสำคัญมาก หากเราทำตาม ลำดับตรรกะ :
$ awk ' /OUTPUT/{flag=1}flag;/END/{flag=0} ' pat.dat
OUTPUT
top 2
bottom 1
left 0
right 0
page 66
ENDแท็กรูปแบบจะแสดงผ่านเอาต์พุต
เหตุผล: หลังจากพบรูปแบบ OUTPUT พุทธง จะเปิดใช้งานเนื่องจากการกระทำ ต่อไป ขึ้นอยู่กับการตั้งค่าสถานะนี้บันทึกจะถูกพิมพ์
เราสามารถหลีกเลี่ยงพฤติกรรมนี้ การเปิดใช้งานการเปิดใช้งานการตั้งค่าสถานะ เป็น ขั้นตอนสุดท้าย ของการไหล
สมมติว่าไฟล์นี้:
$ cat space.dat
10.80 kb
60.08 kb
35.40 kb
2.20 MB
1.10 MB
40.80 kb
3.15 MB
20.50 kbงานของเราคือการคำนวณบันทึก น้ำหนักรวม ของเราใน Mega Bytes :
$ awk ' {total+= $1 / ($2=="kb" ? 1024: 1)}
END{print total} ' space.dat
6.61365เพื่อให้เข้าใจว่า มันทำงานได้อย่างไร แนวคิดหนึ่งต้องชัดเจน ผู้ดำเนินการ [ternary] (หัวข้อของโพสต์เก่า)
total จะถูกใช้เพื่อ สะสม การแบ่งแยกของฟิลด์แรก $1 โดย $2 ที่สองที่จะเก็บค่าที่กำหนดโดย ผู้ประกอบการ Ternary : 1024 เมื่อ $2 เท่ากับ kb และ 1 หากไม่จำเป็นต้องมีการแปลง
ในที่สุดเราพิมพ์ค่า total ในบล็อก END
แหล่งที่มาดั้งเดิม:
$ cat group.dat
string1
string2
string3
string4
string5
string6
string8ภารกิจของเราคือการจัดกลุ่มบันทึกใน บล็อกของสามคอลัมน์ เช่นนี้:
string1 string2 string3
string4 string5 string6
string8 มันอาจดูซับซ้อน แต่ จะง่ายขึ้นมาก ถ้าเราเข้าใจวิธีใช้ ตัวคั่นฟิลด์เอาต์พุต OFS :
$ awk ' ORS = NR%3 ? FS : RS; END{print "n"} ' group.dat
string1 string2 string3
string4 string5 string6
string8 หากเราตั้ง ORS เป็นอักขระ ที่ว่าง เปล่าค่าเริ่มต้น FS เอาต์พุตทั้งหมดจะกลายเป็นบรรทัดเดียว:
$ awk ' ORS=FS; END{print "n"} ' group.dat
string1 string2 string3 string4 string5 string6 string7 ORS = NR%3 ? FS : RS : ในที่สุดเราก็ใช้ ตัวดำเนินการ Ternary (อธิบายก่อนหน้านี้) เพื่อประเมิน [Modulo] NR%3 ผลลัพธ์ของการแบ่งของหมายเลขฟิลด์ปัจจุบัน NR สาม
หาก ส่วนที่เหลือ เป็น จริง ORS จะกลายเป็น FS พื้นที่ ว่าง ไม่เช่นนั้นค่า เริ่มต้นของ RS จะถูกกำหนดจะมีการกำหนดบรรทัด UNIX n
ใน ชีวสารสนเทศศาสตร์ [FASTA] เป็นรูปแบบไฟล์ที่ใช้ข้อความ
มีตัวอย่างต่อไปนี้:
$ cat fasta.dat
> header1
CGCTCTCTCCATCTCTCTACCCTCTCCCTCTCTCTCGGATAGCTAGCTCTTCTTCCTCCT
TCCTCCGTTTGGATCAGACGAGAGGGTATGTAGTGGTGCACCACGAGTTGGTGAAGC
> header2
GGT
> header3
TTATGATเราต้องการ ความยาวทั้งหมดของแต่ละลำดับ และ ประวัติย่อสุดท้าย
ควรมีลักษณะเช่นนี้:
> header1
117
> header2
3
> header3
7
3 sequences, total length 127 awk เป็นเครื่องมือที่สมบูรณ์แบบสำหรับ ความพยายามในการรายงาน นี้สำหรับตัวอย่างนี้เราจะใช้:
awk ' /^>/ { if (seqlen) {
print seqlen
}
print
seqtotal+=seqlen
seqlen=0
seq+=1
next
}
{
seqlen += length($0)
}
END{print seqlen
print seq" sequences, total length " seqtotal+seqlen
} ' fasta.dat
การกระทำครั้งแรก เชื่อมโยง กับการตรวจจับส่วนหัว /^>/ นั่นเป็นเพราะดารา ส่วนหัวทั้งหมด ที่มีตัวละคร >
เมื่อ seqlen ไม่ได้ ค่าของมันที่เก็บความยาวลำดับก่อนหน้าจะถูกพิมพ์ไปยัง stdout ที่แนบมากับส่วนหัวใหม่ seqtotal ได้รับการปรับปรุงและ seqlen เริ่มต้นเพื่อให้บริการลำดับถัดไป ในที่สุดเราก็หยุดการประมวลผลบันทึกเพิ่มเติมด้วย next
การกระทำที่สอง {seqlen += length($0)} ใช้เพื่ออัปเดต seqlen รวมความยาวระเบียนทั้งหมด
จุดประสงค์ ของกฎ END คือการแสดงลำดับ ที่ไม่ได้กำหนด และผลรวม
เคล็ดลับ ที่นี่คือการพิมพ์ความยาว ลำดับก่อนหน้านี้ เมื่อเราพบ ส่วนหัวใหม่
เมื่อเราประมวลผลบันทึกแรก seqlen ไม่มีค่าดังนั้นเราจึงข้ามการสร้างภาพข้อมูล
แหล่งที่มา:
$ cat report.dat
snaps1: Counter: 4966
Opens: Counter: 357283
Instance: s.1.aps.userDatabase.mount275668.attributes
snaps1: Counter: 0
Opens: Counter: 357283
Instance: s.1.aps.userDatabase.test.attributes
snaps1: Counter: 5660
Opens: Counter: 37283
Instance: s.1.aps.userDatabase.mount275000.attributes หน้าที่ ของเรา: สร้าง รายงาน เพื่อแสดง snaps และ instance แต่ เฉพาะเมื่อแท็กตัวนับแรก SNAP มากกว่าศูนย์
ผลลัพธ์ที่คาดหวัง:
snaps1: Counter: 4966
Instance: s.1.aps.userDatabase.mount275668.attributes
snaps1: Counter: 5660
Instance: s.1.aps.userDatabase.mount275000.attributesเรากำลังเล่นอีกรอบ รูปแบบ และ ธง :
awk ' {$1=$1}
/snaps1/ && $NF>0{print;f=1}
f && /Instance/ {print;f=0} ' report.dat สำหรับ ทุกการบันทึก การดำเนินการครั้งแรกจะถูกดำเนินการ มันบังคับให้ awk สร้างใหม่ทั้งหมด โดยใช้ค่าปัจจุบันสำหรับ OFS 3
เคล็ดลับนี้ช่วยให้เราสามารถแปลง ตัวคั่นหลายช่องว่าง เป็น ถ่านเดียว ค่า เริ่มต้น สำหรับตัวคั่นฟิลด์เอาต์พุต
มาดูกันเถอะ:
$ awk ' 1 ' text.dat
one two
three four$ awk ' $1=$1 ' text.dat
one two
three four การกระทำที่สอง จะ ถูกเรียกใช้ เมื่อพบรูปแบบและฟิลด์สุดท้ายมากกว่าศูนย์ /snaps1/ && $NF>0
awk พิมพ์บันทึกและกำหนดค่า ที่แท้จริง ให้กับ print;f=1
ขั้นตอนสุดท้าย: เมื่อธงเป็น จริง และรูปแบบ อินสแตนซ์ ในบรรทัด f && /Instance/ , แสดงบรรทัดและปิดการใช้งานธง: print;f=0
สมมติว่าคลังเก็บสองรายการ:
$ cat join1.dat
3.5 22
5. 23
4.2 42
4.5 44$ cat join2.dat
3.5
3.7
5.
6.5 เราต้องการระเบียนจากอันแรก join1.dat เมื่อฟิลด์แรกอยู่ในช่วงที่สอง join2.dat
ผลลัพธ์ควรเป็น:
3.5 22
5. 23เราสามารถใช้ ยูทิลิตี้ unix เข้าร่วมได้ แน่นอน แต่เราจำเป็นต้องเรียงลำดับไฟล์แรก:
$ join <( sort join1.dat ) join2.dat
3.5 22
5. 23 ไม่จำเป็นใน awk :
$ awk ' NR == FNR{a[$1];next}
$1 in a ' join2.dat join1.datมาศึกษาตัวกรองและการกระทำ:
NR == FNR : หมายเลขบันทึก เท่ากับ หมายเลขไฟล์บันทึก หมายความว่าเรากำลังประมวลผลไฟล์แรกที่แยกวิเคราะห์ไปยัง awk : join2.dat
การกระทำคู่ a[$1];next คือการเพิ่มค่าโมฆะใหม่ลงในอาร์เรย์ที่จัดทำดัชนีโดยฟิลด์แรก คำสั่ง next จะ ทำลาย การประมวลผลบันทึกและส่งผ่านโฟลว์ไปยังข้อความ ถัดไป
สำหรับ การดำเนินการครั้งที่สอง NR != FNR ถูกนำไปใช้โดยปริยายและส่งผลกระทบต่อ join1.dat เงื่อนไขที่สองคือ $1 in a ซึ่งจะเป็น จริง เมื่อฟิลด์แรกของ join1.dat เป็นคีย์อาร์เรย์
สิ่งเหล่านี้คือ UNIX Classics :
$ cat /etc/group
dba:x:001:
netadmin:x:002:$ cat /etc/passwd
jd001:x:1032:001:Javier Diaz:/home/jd001:/bin/rbash
ag002:x:8050:002:Alejandro Gonzalez:/home/ag002:/bin/rbash
jp003:x:1000:001:Jose Perez:/home/jp003:/bin/bash
ms004:x:8051:002:Maria Saenz:/home/ms004:/bin/rbash
rc005:x:6550:002:Rosa Camacho:/home/rc005:/bin/rbashเป้าหมายของเรารายงานเช่นนี้:
d001:dba
ag002:netadmin
jp003:dba
ms004:netadmin
rc005:netadminเราต้องการ โฟลว์หลายไฟล์ ตามที่เราศึกษาในตัวอย่างสุดท้ายของเรา:
$ awk -F : ' NR == FNR{g[$3]=$1;next}
$4 in g{print $1""FS""g[$4]} ' /etc/group /etc/passwd ในการประมวลผล /etc/group เราทำซ้ำการเปรียบเทียบ NR == FNR จากนั้นจัดเก็บ ชื่อของกลุ่ม $1 ที่จัดทำดัชนีโดย ID $3 : g[$3]=$1 ในที่สุดเรา ก็หยุด การประมวลผลบันทึกเพิ่มเติมด้วย next
เงื่อนไขที่สอง จะกำหนดเป้าหมายเท่านั้น /etc/passwd ระเบียนเมื่อฟิลด์ที่สี่ $4 ( ID กลุ่ม ) มีอยู่ในอาร์เรย์ $4 in g เราจะพิมพ์ การเข้าสู่ระบบ และค่าที่ชี้โดยอาร์เรย์ ที่จัดทำดัชนีโดยกลุ่ม ID g[$4] ดังนั้น: print $1""FS""g[$4]
ตัวอย่างเอาต์พุตยูทิลิตี้ผู้ใช้:
$ users
negan rick bart klashxx klashxx ironman ironman ironmanเราจะ นับ ล็อกออนต่อผู้ใช้
$ users | awk ' {a[$1]++}
END{for (i in a){print i,a[i]}} ' RS= ' + '
rick 1
bart 1
ironman 3
negan 1
klashxx 2การกระทำจะดำเนินการสำหรับบันทึกทั้งหมด
a[$1]++ : นี่คือ ตัวนับ สำหรับ ผู้ใช้ แต่ละคน $1 จะเพิ่มขึ้นค่าที่แหลม (VAR ที่ไม่ได้กำหนดค่ามีค่าตัวเลขเป็นศูนย์)
ในตอน END บล็อก วนซ้ำอาร์เรย์ ตามคีย์ และค่าที่เก็บไว้เพื่อนำเสนอผลลัพธ์
เอาต์พุต ทั่วไป :
$ uptime
11:08:51 up 121 days, 13:09, 10 users, load average: 9.12, 14.85, 20.84เราจะได้รับ ค่าเฉลี่ยโหลด ทั้งหมดได้อย่างไร?
$ uptime | awk ' {printf "Load average mean: %0.2fn",
($(NF-2)+$(NF-1)+$(NF))/3 } ' FS= ' (:|,) + '
Load average mean: 14.94นี่คือเทคนิคใหม่
เรากำลังใช้ [regex] เป็นตัวคั่นฟิลด์ (:|,) + ดังนั้น FS สามารถเป็น ลำไส้ใหญ่ และ เครื่องหมายจุลภาค ตามด้วย ศูนย์ช่องว่างหรือมากกว่า
เราเพียงแค่ต้องการ สามฟิลด์สุดท้าย เพื่อดำเนินการเลขคณิตที่ต้องการจากนั้นเราใช้ printf ที่แนบมากับ หน้ากากที่เหมาะสม
ถ้าคุณยังอยู่ที่นี่ ขอบคุณ !!
จากมุมมองของฉัน awk เป็นภาษา ที่มีค่าต่ำกว่า และต้องการความรักมาก❤
หากคุณหิวมากขึ้นแจ้งให้เราทราบในส่วนความคิดเห็นตะโกนและฉันจะพิจารณาส่วนที่สองเพื่อทำภารกิจให้เสร็จ ... เบื่อคุณจนตาย
การเข้ารหัสมีความสุข!
[คู่มือการอ้างอิง UNIX Shell] [QUATING-GUIDE]
[Wikipedia บนท่อ] [ท่อ]
มีหลายครั้งที่สะดวกในการบังคับให้ awk สร้างบันทึกทั้งหมดใหม่โดยใช้ค่าปัจจุบันของ FS และ OFS
ในการทำเช่นนี้เราใช้การมอบหมายที่ไร้เดียงสา: $1 = $1 ↩ 2
คำตอบด่วนเป็นเพียง ทางลัด เพื่อหลีกเลี่ยงการใช้คำสั่งการพิมพ์
ใน awk เมื่อเงื่อนไขได้รับการจับคู่ การกระทำเริ่มต้น คือการพิมพ์บรรทัดอินพุต
$ echo "test" |awk '1'
เทียบเท่ากับ:
echo "test"|awk '1==1'
echo "test"|awk '{if (1==1){print}}'
นั่นเป็นเพราะ 1 จะเป็น [จริง] เสมอ