Thuta Learning
Bash / Shell Scripting
IntermediateDevOps & Toolsbeginner

awk ဖြင့် Text Processing

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • awk ဖြင့် Text Processing concept ကို နားလည်ရှင်းပြနိုင်ရန်
  • နမူနာ code ကို ကိုယ်တိုင် run ပြီး output စစ်နိုင်ရန်
  • Tutorial Platform project နှင့် production scenario တွင် မှန်ကန်စွာအသုံးချနိုင်ရန်

နားလည်ထားရမယ့် အချက်

grep က line များကို ရှာဖွေပြီး sed က text ကို ပြောင်းလဲသော်လည်း awk သည် လုံးဝကွဲပြားသော unit တစ်ခု — record နှင့် field — ဖြင့် စဉ်းစားသည်။ default အနေဖြင့် line တစ်ခုစီကို whitespace ပေါ်တွင် (သို့မဟုတ် -F ဖြင့် သင်သတ်မှတ်ထားသော delimiter မှတစ်ဆင့်) ခွဲထားပြီး အပိုင်းများကို position အလိုက် $1, $2 စသဖြင့် ရည်ညွှန်းနိုင်စေသည်၊ $0 က line တစ်ခုလုံးကို အမြဲဆိုလိုပြီး NF က လက်ရှိ line ပေါ်ရှိ field အရေအတွက်၊ NR က လက်ရှိ line ၏ record number — input တစ်ခုလုံးတစ်လျှောက် running counter ကို ဆိုလိုသည်။ ဤ field-based model က data သည် column များအဖြစ် structure ဖွဲ့ထားသည့်အချိန်တိုင်း awk ကို သဘာဝကျသော tool အဖြစ် ဖြစ်စေသည် — CSV export တစ်ခု၊ /etc/passwd ကဲ့သို့ colon-separated file တစ်ခု၊ သို့မဟုတ် ps သို့မဟုတ် df ကဲ့သို့ command များ၏ columnar output။ awk ကို grep နှင့် sed ထက် ပို၍ ကွဲပြားစေသည့်အချက်မှာ line တစ်ကြောင်းကို သီးခြားစီ process လုပ်ရုံမျှသာ ကန့်သတ်မထားခြင်းဖြစ်သည် — ဖတ်လိုက်သော line တစ်ခုစီတစ်လျှောက် ordinary variable များကို သုံး၍ state ကို သယ်ဆောင်နိုင်ပြီး၊ နောက်ဆုံး line ပြီးနောက် တစ်ကြိမ်တည်း END block အတွင်းမှ ထို accumulated state ကို လုပ်ဆောင်နိုင်သည်။ ၎င်းသည် data ကို နှစ်ကြိမ် ဖတ်ရန် သို့မဟုတ် အခြား language ဖြင့် program အသေးလေးတစ်ခု ရေးရန်မလိုဘဲ single pass တစ်ခုတည်းတွင် running total သို့မဟုတ် average ကို တွက်ချက်ရန် အတိအကျပင်ဖြစ်သည် — sum ကဲ့သို့ variable တစ်ခုသည် main pattern-action block အတွင်း line တစ်ခုစီပေါ်တွင် accumulate ဖြစ်နေပြီး၊ အတိအကျ တစ်ကြိမ်တည်း run သော END block တွင် final aggregated ရလဒ်ကို print ထုတ်သည်။

လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်

employee name၊ department နှင့် salary များပါသော CSV export တစ်ခုရှိပြီး department တစ်ခုရှိ သူတိုင်းကို list ထုတ်ရန် သို့မဟုတ် total payroll ကို တွက်ချက်ရန် လိုအပ်သည်ဟု ဆိုကြပါစို့ — ဤ lesson ၏ data_file တွင် alice,engineering,72000 ကဲ့သို့ row များပါဝင်ပြီး ဤ scenario အတိအကျပင်ဖြစ်သည်။ grep သည် 'engineering' ဟူသော word ပါသော line များကို ရှာနိုင်သော်လည်း column ဟူသော concept လုံးဝမရှိသောကြောင့် name field ကိုတစ်ခုတည်း ခွဲထုတ်၍မရသလို someone ၏ job title အတွင်း department name ကြုံတွေ့ပါက ဖယ်ထုတ်၍လည်း မရနိုင်ပါ; sed ကလည်း arithmetic အတွက် ဖန်တီးမထားပါ။ awk က ဤ gap ကို တိုက်ရိုက် ဖြည့်ဆည်းပေးသည်။ -F, ကို သတ်မှတ်ခြင်းက line တစ်ခုစီကို whitespace အစား comma ပေါ်တွင် ခွဲရန် awk ကို ညွှန်ကြားသည်၊ ၎င်းသည် $1, $2, $3 တို့ name, department, salary နှင့် အသီးသီး ကိုက်ညီစေသည့်အချက်ပင်ဖြစ်သည် — awk -F, '{print $1}' က name များကိုသာ၊ awk -F, '{print $1, $2}' က name နှင့် department ကို အတူတကွ ပြသသကဲ့သို့ပင်ဖြစ်သည်။ column အလိုက် filter လုပ်ခြင်းသည် pattern-action pair တစ်ခုဖြစ်သည် — $2 == "engineering" { print $1 } သည် ဒုတိယ field ကိုက်ညီသော line များပေါ်တွင်သာ print action ကို run စေသည်၊ ၎င်းသည် sed သို့မဟုတ် grep ကို လုံးဝ မထိမကိုက်ဘဲ code က engineering employee များကိုသာ list ထုတ်ပေးနည်းပင်ဖြစ်သည်။ aggregation line နှစ်ကြောင်းက awk ၏ accumulation model ကို တိုက်ရိုက် ပြသသည် — {sum += $3} END {print sum} က salary field ကို line တစ်ခုစီတွင် sum ထဲသို့ ပေါင်းထည့်ပြီး payroll total အတွက် အဆုံးတွင် တစ်ကြိမ်တည်း print ထုတ်သည်၊ count++ ကို ထပ်ထည့်ပြီး END block တွင် sum ကို count ဖြင့် စားလိုက်ခြင်းက single pass တစ်ခုတည်းအတွင်းမှာပင် average ကို တွက်ချက်ပေးသည်။

အတူတူ စမ်းရေးကြည့်မယ်

bash
#!/bin/bash
data_file=$(mktemp)
cat > "$data_file" <<EOF
alice,engineering,72000
bob,sales,54000
carol,engineering,81000
dave,marketing,60000
EOF

echo "First field (names) for each line:"
awk -F, '{print $1}' "$data_file"

echo ""
echo "Name and department (fields 1 and 2):"
awk -F, '{print $1, $2}' "$data_file"

echo ""
echo "Number of fields on the first line:"
awk -F, 'NR==1 {print NF}' "$data_file"

echo ""
echo "Only engineering employees:"
awk -F, '$2 == "engineering" {print $1}' "$data_file"

echo ""
echo "Total salary across all employees:"
awk -F, '{sum += $3} END {print sum}' "$data_file"

echo ""
echo "Average salary:"
awk -F, '{sum += $3; count++} END {print sum / count}' "$data_file"

rm -f "$data_file"
You should see
ဤ script ကို run လိုက်လျှင် အောက်ပါအတိုင်း output ရရှိမည်−

First field (names) for each line:
alice
bob
carol
dave

Name and department (fields 1 and 2):
alice engineering
bob sales
carol engineering
dave marketing

Number of fields on the first line:
3

Only engineering employees:
alice
carol

Total salary across all employees:
267000

Average salary:
66750

၅ မိနစ် စမ်းကြည့်

product name၊ category နှင့် price ဟူသော column သုံးခု ပါဝင်သည့် colon-separated text file တစ်ခုကို product လေးခုအတွက် ဖန်တီးပါ။ ထို့နောက် category တစ်ခုတည်းရှိ product များ၏ name နှင့် price ကိုသာ print ထုတ်သော awk command တစ်ခု၊ product အားလုံး၏ total price ကို print ထုတ်သော command ဒုတိယတစ်ခု ရေးပါ။

သတိလေးတစ်ချက်

whitespace မဟုတ်သော delimiter အတွက် -F ကို သတ်မှတ်ရန် မေ့လျော့ခြင်း — CSV သို့မဟုတ် colon-separated line ကို မှန်ကန်စွာ မခွဲစိတ်ဘဲ field တစ်ခုတည်းအဖြစ် သတ်မှတ်ပစ်လိုက်သည်

column သီးခြားတစ်ခုကို ထုတ်ယူပြီး ပေါင်းရန် regex trick မာရွေ့သော grep သို့မဟုတ် sed ကို သုံးခြင်း — awk က ၎င်းကို တိုက်ရိုက်၊ ပို၍ ယုံကြည်စိတ်ချရစွာ လုပ်ဆောင်ပေးနိုင်သည်

GNU Awk User's GuideBash / Shell Scripting

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • whitespace မဟုတ်သော delimiter အတွက် -F ကို သတ်မှတ်ရန် မေ့လျော့ခြင်း — CSV သို့မဟုတ် colon-separated line ကို မှန်ကန်စွာ မခွဲစိတ်ဘဲ field တစ်ခုတည်းအဖြစ် သတ်မှတ်ပစ်လိုက်သည်
  • column သီးခြားတစ်ခုကို ထုတ်ယူပြီး ပေါင်းရန် regex trick မာရွေ့သော grep သို့မဟုတ် sed ကို သုံးခြင်း — awk က ၎င်းကို တိုက်ရိုက်၊ ပို၍ ယုံကြည်စိတ်ချရစွာ လုပ်ဆောင်ပေးနိုင်သည်
  • နမူနာ code ကို production system ပေါ် တိုက်ရိုက်မစမ်းဘဲ local/test environment တွင် အရင်အတည်ပြုပါ။

လေ့ကျင့်ခန်း

product name၊ category နှင့် price ဟူသော column သုံးခု ပါဝင်သည့် colon-separated text file တစ်ခုကို product လေးခုအတွက် ဖန်တီးပါ။ ထို့နောက် category တစ်ခုတည်းရှိ product များ၏ name နှင့် price ကိုသာ print ထုတ်သော awk command တစ်ခု၊ product အားလုံး၏ total price ကို print ထုတ်သော command ဒုတိယတစ်ခု ရေးပါ။

You'll know it worked when: ဤ script ကို run လိုက်လျှင် အောက်ပါအတိုင်း output ရရှိမည်− First field (names) for each line: alice bob carol dave Name and department (fields 1 and 2): alice engineering bob sales carol engineering dave marketing Number of fields on the first line: 3 Only engineering employees: alice carol Total salary across all employees: 267000 Average salary: 66750