AWK یک زبان برنامه نویسی با کاربرد خاص برای پردازش و استخراج متن است. در سال ۱۹۷۷ در آزمایشگاههای بل نوشته شد.کلمه AWK اول اسمهای سازندهای آن است. و تلفظ آن بصورت «اوک» یا «auk» است. دونستن کلیت AWK بنظر من در در اسکریپت نویسی و کار بار با محیط CLI لینوکس خیلی کمکتون میکنه پس در ادامه با آموزش AWK من همراه باشید.
چرخه اجرای برنامه در AWK
ورودی AWK میتواند فایل، ورودی استاندارد و خروجی دستور دیگر باشد. AWK ورودی را میخواند و بصورت پیشفرض خطبهخط اجرا میکند و این پروسه را تکرار میکند. در صورت نیاز میتوان اجرای خطبهخط را تغییر داد. خلاصه پروسه اجرای AWK بصورت خواندن، اجرا و تکرار است.
ساختار برنامه نویسی AWK
- بلوک شروع
- بلوک بدنه
- بلوک اتمام
بلوک شروع
BEGIN {awk-commands}
این بلوک در شروع برنامه فقط یکبار اجرا میشود و جای مناسبی برای مقداردهی متغییرها است. این بلوک اختیاری است. کلمه کلیدی BEGIN باید با حروف بزرگ نوشته شود. در ادامه با مثالها بیشتر با این بلوک آشنا خواهید شد.
بلوک بدنه
این بلوک برای هر خط از ورودی اعمال میشود و کلمه کلیدی هم ندارد. ساختار آن بصورت شکل زیر است.
/pattern/ {awk-commands}
بلوک اتمام
این بلوک در آخر برنامه اجرا میشود و ساختار آن بصورت شکل زیر است. کلمهEND باید با حروف بزرگ نوشته شود و این بلوک اختیاری است.
END {awk-commands}
مثالهایی از کارکرد AWK
مثال اول
یک فایل متنی با اسم example.txt و با محتوی زیر (چهار کشور برتر در تولید خودرو بر اساس تعداد) را در نظر بگیرید.
$ awk '{print}' example.txt
خروجی
China 27809196 United-States 11314705 Japan 9728528 India 5174645
مثال دوم
$ awk 'BEGIN{print"Country\t\tUnit"} {print}' example.txt
در مثال بالا با بلوک BEGIN کلمات Country و Unit با دو واحد Tab به اول فایل اضافه شد. در بلوک بدنه همهی خطوط چاپ شد. و از بلوک اتمام هم استفاده نشده.
Country Unit China 27809196 United-States 11314705 Japan 9728528 India 5174645
در AWK کارهای پیشرفتهتری هم میشه انجام داد و در ادامه توضیح خواهیم داد. مثلاً اگر بخواهید در مثال بالا جمع کل خودورها را داشته باشید میتونید بصورت زیر عمل کنید.
مثال سوم
$ awk 'BEGIN{print"Country\t\tUnit"} {print $0;sum += $2} END{print "Total:", sum}' example.txt
خروجی
Country Unit China 27809196 United-States 11314705 Japan 9728528 India 5174645 Total: 54027074
توضیحات نحوه عملکرد دستور خیلی ساده است و در ادامه بعد از آشنایی با تکتک المانها راحتر تحلیل خواهید کرد.
فایل برنامه AWK
اگر علاقمند بودید میتوانید دستورات AWK را داخل یک فایل اسکریپت متنی بنویسد. برای صرفه جویی در وقت یا دستورات پیچیده و بزرگ مناسب است. ساختار آن بصورت زیر است.
awk -f commands.awk example.txt
از سوئیچ f- برای معرفی فایل دستورات استفاده میکنیم.
محتوی فایل commands.awk میتواند بصورت ساده زیر باشد:
{print}
یا با تمام بلوکها بصورت زیر باشد.
BEGIN{print"Country\t\tUnit"} {print $0;sum += $2} END{print "Total:", sum}
متغیرهای داخلی در AWK
در AWK تعدادی متغیر داخلی وجود دارد که بصورت پیشفرض دارای مقدار پیشفرض هستند و میتوانیم مقدار آن را تغییر بدیم. در ادامه تعدادی از آنها را باهم بررسی میکنیم.
تعریف فیلد و رکورد:بصورت پیشفرض در AWK هر خط یا سطر یک رکورد است و جداشده های هر سطر را فیلدهای شماره یک تا n نامگذاری میکنیم. البته هر دو مورد متغیر هستن و در ادامه با متغیرهای آنها آشنا میشوید
مثال
China 27809196 United-States 11314705
این متن دارای دو رکورد و هر رکورد دو فیلد دارد.
متغیر n$
این متغیر به فیلد nام اشاره میکند.
متغیر 0$
به کل رکورد اشاره میکند.
متغیر ENVIRON
این متغیر آرایهای از متغییرهای محلی است. برای مثال برای چاپ نامکاربر به ایندکس USER آرایه رجوع میکنیم.
مثال
awk 'BEGIN { print ENVIRON["USER"] }'
متغیر FS
قبل از توضیح FS لازم است یک نکتهای را در AWK بدانید. در AWK مانند دستور cut یا مشابهاتش delimiter داریم که رشته موجود در هر خط متن را با آن جدا میکند و در متغییر های n$ ذخیره میکند. در اینجا FS همان delimiter است که بصورت پیشفرض مقدار Space را دارد.
مثال
$ echo "Milad-Jahandideh" | awk 'BEGIN{FS="-"} {print $2}'
خروجی
Jahandideh
متغیر NF
این متغیر تعداد Field ها را در خود نگه میدارد.
محتوی فایل example.txt بصورت زیر است.
China 27809196 United-States 11314705 Japan 9728528 India 5174645
بعنوان مثال اگر دستور زیر را برای فایل example.txt اعمال کنیم. دستور شمارش تعداد فیلدهای هر خط
awk '{print NF}' example.txt
خروجی
2 2 2 2
متغیر NR
این متغیر عدد رکورد فعلی را نگهداری میکند.
awk '{print NR}' example.txt
خروجی
1 2 3 4
متغیر RS
این متغیر در حقیقت delimiter رکوردها است.
متغیر RSTART
این متغیر در پیدا کردن یک رشته یا کاراکتر در داخل یک رشته دیگر با تابع match استفاده میشود. به مثال زیر توجه کنید.
$ awk 'BEGIN { if (match( "Micro Designer Electronic", "nic")) { print RSTART } }' 23
ما دنبال “nic” در داخل رشته “Micro Designer Electronic” بودیم. و خروجی ایندکس یا جایگاه اولین کاراکتر آن در رشته است.
عملگرها
عملگرهای مختلفی را AWK از جمله محاسباتی، افزایشی و کاهشی،نسبی، منطقی و غیره را پشتیبانی میکند.
مثال جمع دو عدد
$ awk 'BEGIN { a = 85; b = 85; print (a + b) }' 170
مثال تفریق دو عدد
$ awk 'BEGIN { a = 85; b = 85; print (a - b) }' 0
مثال ضرب دو عدد
$ awk 'BEGIN { a = 85; b = 85; print (a * b) }' 7225
مثال متغییر افزایشی
$ awk 'BEGIN { a = 10; ++a; print a}' 11
مثال متغیر کاهشی
در این مثال کمی سبک زبان C نیز اضافه شده.
$ awk 'BEGIN { a = 10; a--; printf "a = %d\n", a}' a = 9
مثال تقسیم
$ awk 'BEGIN { n = 200; n /= 5; print "Number =", n }' Number = 40
مثال مقایسه و شرط
$ awk 'BEGIN { a = 10 ; b = 1; if (a < b) print a " < " b ; else print a " > " b }' 10 > 1
مثال عملگر AND منطقی
$ awk 'BEGIN {num = 5; if (num >= 0 && num <= 9) printf "%d is between 0-9\n", num }' 5 is between 0-9
مثال عملگر توان
$ awk 'BEGIN { a = 5; a = a^2; print "a =", a }' a = 25
مثال عملگر اتصال به رشته به هم
awk 'BEGIN { str1 = "Milad"; str2 = "Jahandideh"; str3 = str1 str2; print str3 }' MiladJahandideh
آرایه ها در AWK
در AWK آرایه ها مثل زبان C هستن با این تفاوت که نوع ندارند و هر نوع مقداری را میتونن داشته باشن.
array_name[index] = value
به عنوان مثال در دستور زیر اعداد را با رشته در یک آرایه قرار دادیم.
$ awk 'BEGIN {arr[0] = "Ubuntu"; arr[1] = 1804; print arr[0] arr[1]}' Ubuntu1804
عبارتهای باقاعده در AWK
عملگر پیدا کردن رشتههای باقاعده “~”
برای بررسی وجود رشتههای باقاعده داخل فیلدها از عملگر “~” استفاده میکنیم.
مثال
$ awk '$1 ~ /8$/' example.txt Japan 9728528
البته بدون عملگر “~” هم میتوانید مقایسه کنید فقط در این حالت کل رکورد را بررسی میکند.
$ awk '$1 ~ /J./' example.txt Japan 9728528
دستورات شرطی در AWK
دستورات شرطی در AWK مانند بقیه زبانهای برنامهنویسی هستن.
if (condition) action
مثال if ساده
$ awk 'BEGIN { n=99 ; if (n < 100) print n "<" 100 }' 99<100
مثال if – else
$ awk 'BEGIN { n=990 ; if (n < 100) print n "<" 100 ; else print n ">" 100 }' 990>100
حلقههای تکرار در AWK
حلههای تکرار AWK مانند C است. به مثالهای زیر توجه کنید.
مثال حله FOR
$ awk 'BEGIN { for (i=0;i<10;i++) print i }' 0 1 2 3 4 5 6 7 8
مثال حلقه WHILE
$ awk 'BEGIN {i=0 ; while (i<10) {print i;i++} }' 0 1 2 3 4 5 6 7 8 9
توابع در AWK
توابع داخلی
بصورت داخلی AWK از رنج بزرگی از توابع مثل توابع ریاضیاتی و توابع رشته ها پشتیبانی میکند.
مثال
$ awk 'BEGIN { a=90 ; print sin(0) } ' 0
توابع کاربر
بجز توابع داخلی خود کاربر نیز میتواند مثل بقیه زبانهای برنامه نویسی تابع تعریف و از آن در برنامه استفاده کند.
function function_name(argument1, argument2, ...) { function body }
مثال
برای نوشتن تابع یک فایل awk. ایجاد میکنیم و دستورات را داخل آن مینویسیم.
محتوی فایل commands.awk
function my_func(a,b){ print a+b } BEGIN { my_func(18,1) }
اجرا
$ awk -f commands.awk 19
پردازش فایل XML با AWK
فرض کنید یک فایل XML با محتوی زیر داریم.
<note> <to>Reza</to> <from>Ali</Ffrom> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> <note> <to>Hossein</to> <from>Ali</Ffrom> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>
و میخواهیم awk هر وقت کلمه hossein را جستوجو و پیدا کرد کل تگ note را برای ما نشان دهد.
$ awk 'BEGIN {RS="\n\n"} $0 ~ "Hossein" {print $0}' file.xml
خروجی
<note> <to>Tove</to> <from>Hossein</Ffrom> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>
توابع داخلی در AWK
یکسری توابع از پیش تعریف شده در AWK موجود است و میتوانیم از آنها در نوشتن دستنویسها استفاده کنیم. البته تقریباً توابع ضروری را در برمیگیرد.
توابع ریاضی
توابع ریاضی شامل سینوس، کسینوس، تانژانت، لگاریتم، تولید عدد تصادفی و غیره است.
مثال تولید عدد تصادفی
$ awk 'BEGIN { print "Random Number :" , rand()'} Random Number : 0.260512
مثال جذر
$ awk 'BEGIN { print "sqrt of 25 :" , sqrt(25)'} sqrt of 25 : 5
مثال سینوس
$ awk 'BEGIN { PI = 3.14159265 param = 30.0 result = sin(param * PI /180) printf "The sine of %f degrees is %f.\n", param, result }' The sine of 30.000000 degrees is 0.500000.
توابع رشته
این توابع برای کار با رشتهها طراحی شدن.توابعی نظیر پیدا کردن یک کاراکتر یا رشته داخل رشته دیگر، پیدا کردن اولین نقطه شروع کاراکتر در رشته، جابجایی در رشته و توابع مشابه.
تابع جایگزینی رشته
تابع gsub(regex, sub, string) برای جایگزینی sub به جای رشته regex در متغیر string استفاده میشود. متغیر اول از نوع رشتههای باقاعده میتواند باشد. مثال زیر رشته World را با رشته Milad در متغیر strجایگزین میکند.
$ awk 'BEGIN { str = " Hello, World" ;print str ;gsub("World","Milad",str); print str}' Hello, World Hello, Milad
تابع match
این تابع یک رشته را داخل رشته دیگری جستوجو میکند و محل شروع رشته را برمیگرداند.
$ awk 'BEGIN { str = "I am Milad, Who are you?" ; print match(str,"Who") }' 13
تعریف تابع در awk
علاوه بر توابع داخلی کاربر نیز میتواند توابعی را تعریف و در ادامه آنها را فراخوانی کند.
مثال
یک فایل awk. ایجاد کنید.
$ vim functions.awk
و توابع را داخل آن تعریف و در آخر فایل آن را فراخوانی کنید.
# Returns minimum number function find_min(num1, num2){ if (num1 < num2) return num1 return num2 } # Returns maximum number function find_max(num1, num2){ if (num1 > num2) return num1 return num2 } # Main function function main(num1, num2){ # Find minimum number result = find_min(10, 20) print "Minimum =", result # Find maximum number result = find_max(10, 20) print "Maximum =", result } # Script execution starts here BEGIN { main(10, 20) }
و آن را اجرا کنید.
$ awk -f functions.awk Minimum = 10 Maximum = 20
با توجه به طول عمر awk کاربران حوزه لینوکس و یونیکس استفادههای خلاقانهای را از آن داشتهاند. و اگر موردی بود خوشحال میشم در قسمت کامنتها بنویسید.
- منبع: وبسایت tutorialspoint
امیدوارم «آموزش AWK – برنامه نویسی به زبان AWK» براتون مفید واقع شده باشه و کامنت یادتون نره 🙂
اگر این نوشته برایتان مفید بود لطفا کامنت بنویسید.
سلام من میخوام تو فایل log سرورم خط که های اسم یک متغیر دارن رو جدا کنم. میخواستم اگه میشه راهنمایی کنید
سلام علی آقا ببخشید دیر جواب میدم. کار زیاد است. لطفا نمونه لاگ خودتان را ایجا بذارید و بگید کدوم پارامتر را میخواهید ازش جدا کنید…منم براتون انجام بدم کامندش را اینجا بذارم.