နားလည်ထားရမယ့် အချက်
grep နှင့် sed တို့သည် shell scripting တွင် အသုံးအများဆုံး tool နှစ်ခုဖြစ်ပြီး၊ ပြဿနာကို ကွဲပြားစွာ ဖြေရှင်းပေးသည် — grep သည် မည်သည့်အရာကိုမျှ မပြောင်းလဲဘဲ pattern နှင့် ကိုက်ညီသော line များကို ရှာဖွေပေးပြီး၊ sed သည် text ကို stream ဖြင့် ဖြတ်သန်းစဉ် ပြောင်းလဲပေးသည်၊ အများဆုံးအားဖြင့် text တစ်ခုကို အခြားတစ်ခုနှင့် အစားထိုးခြင်းဖြင့်ဖြစ်သည်။ grep ၏ flag များက ရိုးရိုးရှာဖွေမှုတစ်ခုကို ပို၍ တိကျစေသည် — -i က case ကို လျစ်လျူရှုပြီး၊ -v က match ကို ပြောင်းပြန်ပြန်ကာ မကိုက်ညီသော line များကို ပြသပေးကာ၊ -n က result တစ်ခုစီ၏ ရှေ့တွင် line number ကို ပေါင်းထည့်ပေးသဖြင့် file ထဲမည်သည့်နေရာမှ ရလာသည်ကို သိစေကာ၊ -c က matching line များအစား count ကို ပြန်ပေးကာ၊ -E က extended regular expression ကို ဖွင့်ပေးသဖြင့် + နှင့် ? ကဲ့သို့ metacharacter များကို backslash ဖြင့် escape မလုပ်ဘဲ အလုပ်လုပ်စေသည်။ sed ၏ core operation မှာ substitution command, s/old/new/ ဖြစ်ပြီး default အနေဖြင့် line တစ်ခုစီပေါ်ရှိ ပထမ match ကိုသာ အစားထိုးသည်; g flag ကို ထပ်ထည့်လိုက်လျှင် line ပေါ်ရှိ match အားလုံးကို အစားထိုးသွားမည်ဖြစ်ပြီး၊ default behavior ကို မေ့လွယ်တတ်သောကြောင့် ဤအချက်က လူများကို အမြဲ ရှုပ်ထွေးစေတတ်သည်။ substitution ကိုယ်တိုင်ကဲ့သို့ပင် အရေးကြီးသည့်အချက်မှာ ၎င်းကို မည်သို့ apply လုပ်မည်နည်း ဆိုသည့်အချက်ဖြစ်သည် — flag မပါသော sed သည် ပြောင်းလဲထားသော text ကို stdout သို့ print ထုတ်ရုံသာ လုပ်ပြီး original file ကို မထိခိုက်ဘဲ ချန်ထားသော်လည်း၊ sed -i ကမူ file ကို in place edit လုပ်ပြီး — sed -i.bak ကမူ edit အတူတူပင်လုပ်ရင်း file ၏ .bak copy ကို ယခင်အတိုင်း ချန်ထားပေးသည်၊ ၎င်းသည် သင်၏ regex သည် သင်မျှော်လင့်ထားသည့်အရာအတိုင်း အတိအကျမလုပ်ဆောင်သည့် အခိုက်အတန့်တွင် အလွန်အရေးကြီးလာသည်။
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
အလွန်အသုံးများသော task တစ်ခုမှာ configuration file တစ်ခုအတွင်းရှိ setting တစ်ခုကို ပြင်ခြင်းဖြစ်သည် — ဥပမာ service ၏ port number ပြောင်းခြင်း သို့မဟုတ် debug flag ကို toggle လုပ်ခြင်း — file ကို လက်ဖြင့် အကြိမ်တိုင်း edit မလုပ်ဘဲ deployment script တစ်ခုအတွင်းမှသာ ပြုလုပ်ခြင်းဖြစ်ပြီး၊ ဤ lesson ၏ code သည် workflow အပြည့်အစုံကို ဖော်ပြထားသည်။ grep ကို defensively သုံးခြင်းဖြင့် စတင်သည် — grep "port" က setting သည် file ထဲတွင် အမှန်တကယ် ရှိကြောင်းနှင့် ၎င်း၏ လက်ရှိ value ကို တစ်ခုခု မပြောင်းမီ ပြသပေးပြီး၊ grep -i "host" က file တွင် capitalization မတူညီသော်လည်း case-insensitive search က HOST ကို ရှာတွေ့ကြောင်း ပြသကာ၊ grep -v "^#" က comment line များကို filter ထုတ်ပြီး active setting များကိုသာ ပြသပေးသည် — config file တစ်ခုကို လျင်မြန်စွာ audit လုပ်ရန် အသုံးဝင်သည်။ grep -En "[0-9]+" က extended regex ကို line number နှင့် ပေါင်းစပ်ကာ digit ပါသော line များ ဘယ်နေရာမှာ ရှိသည်ကို အတိအကျ ပြသသည်။ setting ကို အတည်ပြုပြီးနောက် sed "s/port=8080/port=9090/" သည် file ကို မထိခိုက်ဘဲ ပြောင်းလဲထားသော text ကို print ထုတ်ခြင်းဖြင့် ပြောင်းလဲမှုကို preview လုပ်ပေးသည် — in-place edit တစ်ခု commit မလုပ်မီ ကောင်းသော အလေ့အထတစ်ခုဖြစ်သည်။ actual edit ဖြစ်သော sed -i.bak "s/debug=true/debug=false/" သည် debug flag ကို toggle လုပ်ရင်း original ၏ .bak copy ကို ချထားပေးသည် — ထို့ကြောင့် regex က မမျှော်လင့်ထားသည့်အရာတစ်ခုခုကို ကိုက်ညီသွားခဲ့လျှင် သို့မဟုတ် file မှားယွင်းစွာ target လုပ်မိခဲ့လျှင်၊ ယခင် state သည် လုံးဝပျောက်ကွယ်သွားမည့်အစား mv command တစ်ခုတည်းဖြင့် ပြန်လည်ရယူနိုင်သော အနေအထားတွင် ရှိနေသည်။
အတူတူ စမ်းရေးကြည့်မယ်
#!/bin/bash
config_file=$(mktemp)
cat > "$config_file" <<EOF
# Server configuration
host=localhost
port=8080
debug=true
timeout=30
EOF
echo "Lines matching 'port':"
grep "port" "$config_file"
echo ""
echo "Case-insensitive search for 'HOST':"
grep -i "host" "$config_file"
echo ""
echo "Lines NOT starting with #:"
grep -v "^#" "$config_file"
echo ""
echo "Count of settings lines (containing =):"
grep -c "=" "$config_file"
echo ""
echo "Lines with a number, using extended regex:"
grep -En "[0-9]+" "$config_file"
echo ""
echo "Replacing port value with sed:"
sed "s/port=8080/port=9090/" "$config_file"
echo ""
echo "Editing the file in place (with a backup):"
sed -i.bak "s/debug=true/debug=false/" "$config_file"
cat "$config_file"
rm -f "$config_file" "$config_file.bak"ဤ script ကို run လိုက်လျှင် အောက်ပါအတိုင်း output ရရှိမည်−
Lines matching 'port':
port=8080
Case-insensitive search for 'HOST':
host=localhost
Lines NOT starting with #:
host=localhost
port=8080
debug=true
timeout=30
Count of settings lines (containing =):
4
Lines with a number, using extended regex:
3:port=8080
5:timeout=30
Replacing port value with sed:
# Server configuration
host=localhost
port=9090
debug=true
timeout=30
Editing the file in place (with a backup):
# Server configuration
host=localhost
port=8080
debug=false
timeout=30၅ မိနစ် စမ်းကြည့်
user name အနည်းငယ်နှင့် age များကို colon ဖြင့် ခွဲထားသော text file အသေးလေးတစ်ခု ဖန်တီးပါ။ ပေးထားသော age prefix pattern ထက်ကြီးသော user line များကိုသာ grep ဖြင့် ရှာဖွေပြီး၊ sed ဖြင့် user တစ်ဦး၏ age ကို ပြောင်းလဲကာ original file ၏ .bak backup ကို ချန်ထားပါ။
သတိလေးတစ်ချက်
အရေးကြီးသော file တစ်ခုပေါ်တွင် backup suffix မပါဘဲ sed -i ကိုသုံးခြင်း — regex စာလုံးပေါင်းမှား ရိုက်မိသည့်အခါ ပြန်ပြင်၍မရသော တစ်ခုတည်းသော copy ကို overwrite လုပ်ပစ်နိုင်သည်
occurrence တိုင်းကို ပြောင်းလိုသော်လည်း sed ၏ substitution တွင် g flag ကို မေ့ထားခြင်း — line တစ်ခုစီတွင် ပထမ match တစ်ခုသာ အစားထိုးခံရသည်
GNU sed Manual — Bash / Shell Scripting