راهنمای آموزشی اسکریپت نویسی - مقدماتی

لطفا برای بهتر دیدن صفحه از firefox استفاده کنید
Bash Guide for Beginners Machtelt Garrels

راهنمای Bash برای نوآموزان

برنامه چاپ »
« خلاصه

متغیرهای Gawk

همانندawk فایل ورودی را پردازش می‌کند، از چند متغیر استفاده می‌کند. برخی قابل تغییر و برخی فقط‌خواندنی می‌باشند.

جداساز فیلد ورودی

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

جداکننده فیلد توسط متغیر داخلی FS نمایندگی می‌شود. توجه داشته باشید که این جداکننده فیلد، متفاوت بامتغیر IFS مورد استفاده در شل‌های سازگار با استاندارد POSIX می‌باشد.

در برنامه awkمقدار متغیر جداکننده فیلد می‌تواند باعملگر تخصیص = تغییر داده شود. غالباً زمان صحیح انجتم این تخصیص در آغاز اجراو قبل از آن‌که هرگونه پردازشی روی ورودی صورت گیرد، میباشد، به طوری که اولین رکورد ورودی با جدا کننده صحیح خوانه شود. برای انجام این مورد از الگوی ویژه BEGIN استفاده کنید.

در مثال زیر، دستوری ساخته‌ایم که تمام کاربران سیستم را با یک توضیح نمایش می‌دهد:

kelly is in ~> awk 'BEGIN { FS=":" } { print $1 "\t" $5 }' /etc/passwd
--output omitted--
kelly	Kelly Smith
franky	Franky B.
eddy	Eddy White
willy	William Black
cathy	Catherine the Great
sandy	Sandy Li Wong

kelly is in ~>

در یک اسکریپت awk، چنین شکلی خواهد داشت:

kelly is in ~> cat printnames.awk
BEGIN { FS=":" }
{ print $1 "\t" $5 }

kelly is in ~> awk -f printnames.awk /etc/passwd
--output omitted--

برای اجتناب از مشکلات، جداکننده‌های فیلد را با احتیاط انتخاب کنید. یک مثال جهت تشریح این مورد: فرض کنید شما ورودی را در سطرهایی به این شکل دریافت می‌کنید:

“Sandy L. Wong, 64 Zoo St., Antwerp, 2000X”

شما یک سطر فرمان یا یک اسکریپت می‌نویسید، که نام شخص در آن رکورد را در خروجی بدهد:

awk 'BEGIN { FS="," } { print $1, $2, $3 }' inputfile

اما یک شحص ممکن است یک PhD، داشته باشد و ممکن است به این شکل نوشته شده باشد:

“Sandy L. Wong, PhD, 64 Zoo St., Antwerp, 2000X”

برنامه awk شما برای این سطر خروجی اشتباه خواهد داشت. اگر لازم بود، یک awk اضافه یا sed برای متحدالشکل نمودن قالب‌های داده ورودی استفاده کنید.

به طور پیش‌فرض جداکننده فیلد ورودی یک یا چند فاصله یاtab می‌باشد.

جداکننده‌های خروجی

جداکننده فیلد خروجی

در خروجی به طور معمول فیلدها با فاصله از یکدیگر جدا می‌گردند. این موقعی آشکار می‌شود که شما ترکیب صحیح برای فرمان print را به کار ببرید، که در آن شناسه‌ها با کاراکتر کاما از یکدیگر جدا شده باشند:

kelly@octarine ~/test> cat test
record1         data1
record2         data2

kelly@octarine ~/test> awk '{ print $1 $2}' test
record1data1
record2data2

kelly@octarine ~/test> awk '{ print $1, $2}' test
record1 data1
record2 data2

kelly@octarine ~/test>

اگر کاراکترهای کاما را در print نگذارید، با فیلدهای خروجی همچون یک شناسه رفتار می‌شود، بنابراین استفاده از جداکننده پیش‌فرض ، OFS چشم‌پوشی می‌گردد.

با تنظیم این متغیر داخلی هر رشته کاراکتری را می‌توان برای جداکننده فیلد خروجی، تخصیص داد.

جداکننده رکورد خروجی

تمام خروجی یک فرمان print یک رکورد خروجی نامیده شده‌است. هر فرمان print یک رکورد خروجی نتیجه می‌دهد، و پس از آن یک رشته‌ای که جداکننده رکورد خروجی, ORS نامیده شده را به خروجی می‌دهد. مقدار پیش‌فرض این متغیر برابر است با “n\”، یک کاراکتر سطر جدید. بنابراین، هر فرمان print یک سطر جداگانه تولید می‌کند.

برای تغییر روش جدا نمودن فیلدها و رکوردهای خروجی، مقادیر جدید به متغیرهای OFS و ORS تخصیص بدهید:

kelly@octarine ~/test> awk 'BEGIN { OFS=";" ; ORS="\n-->\n" } \
{ print $1,$2}' test
record1;data1
-->
record2;data2
-->

kelly@octarine ~/test>

اگر مقدار متغیر ORS شامل یک سطر جدید نباشد، خروجی برنامه در یک سطر منفرد با هم ظاهر می‌شوند.

تعداد رکوردها

متغیر داخلی NR تعداد رکوردهایی که پردازش شده‌اند را نگاه می‌دارد. این متغیر بعد از خوانده شدن یک سطر جدید افزایش می‌یابد. می‌توانید از آن در انتها برای تعداد کل رکوردها، یا در هر رکورد خروجی استفاده کنید:

kelly@octarine ~/test> cat processed.awk
BEGIN { OFS="-" ; ORS="\n--> done\n" }
{ print "Record number " NR ":\t" $1,$2 }
END { print "Number of records processed: " NR }

kelly@octarine ~/test> awk -f processed.awk test
Record number 1:        record1-data1
--> done
Record number 2:        record2-data2
--> done
Number of records processed: 2
--> done

kelly@octarine ~/test>

متغیرهای تعریف شده کاربر

جدای از متغیرهای داخلی، شما می‌‌توانید متغیرهای خودتان را تعریف نمایید. موقعی کهawk با ارجاع به یک متغیری که موجود نیست( که ازپیش تعریف نشده است ) ، روبرو می‌شود، متغیر را ایجاد نموده و یک رشته تهی به آن اختصاص می‌دهد. برای تمام ارجاع های بعدی، مقدار متغیر برابر با آخرین مقدار تخصیص یافته به آن است. متغیرها می‌توانند یک مقدار عددی یا رشته‌ای داشته باشند. محتوای فیلدها نیز می‌تواند به متغیرها تخصیص یابد.

کمیت‌ها را می‌توانید به طور مستقیم با استفاده ازعملگر = اختصاص بدهید, و یا می‌توانید مقدار فعلی متغیر را در ترکیب با سایرعملگرها به کار ببرید:

kelly@octarine ~> cat revenues
20021009        20021013        consultancy     BigComp         2500
20021015        20021020        training        EduComp         2000
20021112        20021123        appdev          SmartComp       10000
20021204        20021215        training        EduComp         5000

kelly@octarine ~> cat total.awk
{ total=total + $5 }
{ print "Send bill for " $5 " dollar to " $4 }
END { print "---------------------------------\nTotal revenue: " total }

kelly@octarine ~> awk -f total.awk test
Send bill for 2500 dollar to BigComp
Send bill for 2000 dollar to EduComp
Send bill for 10000 dollar to SmartComp
Send bill for 5000 dollar to EduComp
---------------------------------
Total revenue: 19500

kelly@octarine ~>

مختصرنویسی شبیه زبان C، مانند ‎VAR+= value‎ نیز قابل قبول است.

مثال‌های بیشتر

مثال‌های بخشی به نام «نوشتن فایل‌های خروجی» موقعی که از یک اسکریپتawk استفاده کنیم آسانتر می‌شود:

kelly@octarine ~/html> cat make-html-from-text.awk
BEGIN { print "<html>\n<head><title>Awk-generated HTML</title></head>\n<body bgcolor=\"#ffffff\">\n<pre>" }
{ print $0 }
END { print "</pre>\n</body>\n</html>" }

موقعی که به جای sed از awk استفاده کنیم، دستور اجرایی نیز سرراست‌تر می‌شود:

kelly@octarine ~/html> awk -f make-html-from-text.awk testfile > file.html

[Tip]مثال‌های Awk در سیستم شما

ما دوباره شما را به دایرکتوری محتوی فایل‌های initscript در سیستم خودتان ارجاع می‌دهیم. دستوری مشابه دستور زیر را برای دیدن مثال‌های عملی بیشتری از کاربرد فرمان awk که به طور گسترده‌ای پراکنده‌اند، وارد کنید:

grep awk /etc/init.d/*

برنامه printf

برای کنترل دقیق‌تر روی قالب‌بندی خروجی نسبت به آنچه به طور معمول با فرمان print فراهم می‌شود، از printf استفاده کنید. فرمان printf می‌تواند برای تعیین عرض فیلد جهت استفاده هریک از اقلام، به کار برود، علاوه بر آن انتخاب‌های متنوع شکل‌دهی اعداد(از قبیل مبنای مورد استفاده برای خروجی، این‌که آیایک توان، یا یک علامت چاپ شود، یا چند رقم اعشار بعد از ممیز باید چاپ شود) را دارد. این موارد با فراهم نمودن یک رشته‌ای که format string نامیده می‌شود، انجام می‌گردد, این رشته کنترل می‌کند که چطور و کجا شناسه‌های دیگر چاپ شوند.

ترکیب دستوری آن همانند دستور printf زبان C می‌باشد، راهنمای معرفی C خود را نگاه کنید. صفحات info فرمان gawk شامل توضیحات کامل آن می‌باشند.

برنامه چاپ »
« خلاصه
ترجمه محمود پهلوانی