آموزش AWK – برنامه نویسی به زبان AWK

AWK یک زبان برنامه نویسی با کاربرد خاص برای پردازش و استخراج متن است. در سال ۱۹۷۷ در آزمایشگاه‌های بل نوشته شد.کلمه AWK اول اسم‌های سازند‌های آن است. و تلفظ آن بصورت «اوک» یا «auk» است. دونستن کلیت AWK بنظر من در در اسکریپت نویسی و کار بار با محیط CLI لینوکس خیلی کمکتون می‌کنه پس در ادامه با آموزش AWK من همراه باشید.

آموزش AWK - برنامه نویسی به زبان AWK

چرخه اجرای برنامه در 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- برای معرفی فایل دستورات استفاده می‌کنیم.

مطلب پیشنهادی:  آموزش کنترل موتور DC با رزبری پای

محتوی فایل 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

عملگر پیدا کردن رشته‌های باقاعده “~”

مطلب پیشنهادی:  آموزش استفاده از کابل کنسول در Raspberry Pi

برای بررسی وجود رشته‌های باقاعده داخل فیلدها از عملگر “~” استفاده می‌کنیم.

مثال

$ 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 موجود است و می‌توانیم از آن‌ها در نوشتن دست‌نویس‌ها استفاده کنیم‌. البته تقریباً توابع ضروری را در برمی‌گیرد.

مطلب پیشنهادی:  اتصال سنسور فاصله‌سنج HC-SR04 به رزبری‌پای

توابع ریاضی

توابع ریاضی شامل سینوس، کسینوس، تانژانت، لگاریتم، تولید عدد تصادفی و غیره است.

مثال تولید عدد تصادفی

$ 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 کاربران حوزه لینوکس و یونیکس استفاده‌های خلاقانه‌ای را از آن داشته‌اند. و اگر موردی بود خوشحال می‌شم در قسمت کامنت‌ها بنویسید.

امیدوارم «آموزش AWK – برنامه نویسی به زبان AWK» براتون مفید واقع شده باشه و کامنت یادتون نره 🙂

اگر این نوشته‌ برایتان مفید بود لطفا کامنت بنویسید.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

2 دیدگاه

  1. سلام من میخوام تو فایل log سرورم خط که های اسم یک متغیر دارن رو جدا کنم. میخواستم اگه میشه راهنمایی کنید

    • میلاد جهاندیده

      سلام علی آقا ببخشید دیر جواب می‌دم. کار زیاد است. لطفا نمونه لاگ خودتان را ایجا بذارید و بگید کدوم پارامتر را میخواهید ازش جدا کنید…منم براتون انجام بدم کامندش را اینجا بذارم.