Awk یک زبان برنامه نویسی همه کاره است که برای پردازش دادههای مبتنی بر متن (text-based) یا فایلها یا جریان دادهها در آزمایشگاه bell در سال ۱۹۷۰ طراحی و ساخته شد.نام awk از نام خانوادگی سازندگانش مشتق شده است ( Alfred Aho, Peter Weinberger, Brian Kernighan)
به هر حال معمولاًً به عنوان رشته حرفهای جدا تلفظ نشده استولی تا حدی که مشابه به صدای نام یک پرنده aak صدا بدهد (که به صورت یک آرم برای زبان عمل میکند مثل آرم روی کتاب زبان برنامه نویسی awk )awk وقتی که به طور کلی با حروف کوچک نوشته میشودبا رجوع به برنامه UNIX وPlan 9 که سایر برنامههای نوشته شده در awk را اجرا میکنند. Awk یک مثال از یک زبان برنامه نویسی است که بطور وسیعی از نوع داده رشته استفاده میکند، آرایههای شرکت پذیر (آرایههایی هستند که اندیس دهی با رشتههای اصلی شدهاند)و عبارتهای منظم.قدرت، اختصار، ومحدودیتهای زبان awk وsed scripts الهام بخش Larry Wall در نوشتن Perl بود. بخاطر حاشیه نویسی انبوه آنها، همه این زبانها اغلب برای نوشتن برنامههای حاشیهای استفاده میشدند. Awk یکی از ابتداییترین ابزارهایی است که در Unix ورژن ۷ ظاهر شدو به عنوان راهی برای اضافه کردن ویژگیهای محاسباتی به خط لوله Unix محبوبیت زیادی به دست آورد. یک ورژن از زبان awk یک ویژگی استاندارد تقریبا هر سیستمعامل جدید شبیه یونیکس که امروزه موجود است میباشد. awk ذکر کننده در مشخصه مجرد یونیکس به عنوان ابزار اجباری سیستمعامل یونیکس میباشد. علاوه بر این برنامه واسط Bourne shell ،awk تنها زبان دیگر اسکریپتی موجود در محیط استاندارد یونیکس میباشد پیاده سازی awk تقریبا به عنوان یک نرمافزار نصب شده برای تمامی سیستمعاملهای دیگر وجود دارد.
ساختار برنامههای Awk
Awk به صورت یک سری از الگوها و فعالیتهای جفتی میباشد که به صورت زیر نوشته میشود.
pattern {action}
که الگوها نمونه یک عبارت هستند و فعالیتها یک سری از دستورها هستند. هر خط ورودی با تمام الگوهای در گردش آزمایش میشود و فعالیت برای هر عبارتی که درست باشد اجرا میشود. ممکن است هم الگو و هم فعالیت حذف شده باشند. پیش فرض الگو به تطبیق دادن هر خط از ورودی است و پیش فرض فعالیت چاپ خط ورودی میباشد. به علاوه یک عبارت ساده awk الگو شروع یا پایان میتواند باعث شود که فعالیت قبل یا بعد از همه خطهای ورودی که خوانده شده است اجرا شود. یا الگو۱ یا الگو ۲ که تطبیق میدهند محدوده خطوط ورودی شروع میشوند با خطی که منطبق بر الگو ۱ و شامل خطی که منطبق بر الگو ۲ میباشد قبل از اینکه دوباره تلاش کند با تطبیق الگو ۱ روی خطوط آینده. به علاوه حسابگر منطقی و عملگر منطقی عبارات Awk شامل عملوند ~ میباشند.که منطبق میکند عبارات منظم با رشته به طوریکه نحوی قندی /regexp/ بدون استفاده از عملگر~ با خط جاری ورودی منطبق میکند.
دستورات Awk
دستورات awk عبارتهایی هستن که جایگزین میشوند به عنوان فعالیت در مثالهای بالا .دستورهای awk میتوانند شامل فراخوانی تابع، انتساب به متغیرها، محاسبات یا هر ترکیبی آز آنها که بشود.awk دارای پشتیبانی داخلی برای خیلی از توابع است awk امکانات بیشتری را توسط چاشنیهای گوناگون فراهم نموده است. همچنین بعضی از کتابخانهها پشتیبانی میکنند شمول کتابخانههای متصل شده پویا را که همچنین میتوانند توابع بیشتری را فراهم کنند. برای اختصار در میان گذاشتن {} از این مثالها حذف خواهد شد. فرمان چاپ برای متن خروجی استفاده میشود. متن خروجی همیشه با یک رشته از پیش تعریف شده پایان داده میشود که فراخوانی میکند خروجی ضبط شده جدا کننده (ORS) که پیش فرض مقدار آن یک خط جدید است. سادهترین شکل این دستور به این صورت است:
print
که نشان دهنده محتویات سطر جاری در awk میباشد. خطها به زمینهها شکسته میشوند و اینها میتوانند به طور جداگانه نمایش داده شوند:
print $1
اولین زمینه از خط جاری را نشان میدهد:
print $1, $3
اولین و سومین زمینه از سطر جاری را نشان میدهد و مجزا شدهاند به وسیله رشته از قبل تعریف شده فراخوانده خروجی زمینه جداسازی (OFS) که پیش فرض مقدار یک کاراکتر فاصله خالی است. اگرچه ممکن است این زمینهها ($X) جهتی را شبیه به متغیرها تعریف کنند (علامت $ نشان دهنده متغیرها در perl میباشد) آنها واقعا به زمینههای سطر جاری مراجعه میکنند. مورد ویژه $۰ مراجعه میکند به خط کامل در حقیقت دستور "print و "print $0" با یکدیگر در طراحی مساوی هستند. دستور چاپ میتواند همچنین محاسبات و فراخوانی تابع را نشان دهد.
print 3+2 print foobar(3) print foobar(variable) print sin(3-2)
خروجی ممکن است که به فایل فرستاده شود:
print "expression" > "file name"
یا در یک لوله :
print "expression" | "command"
متغیرها و نحو
نام متغیرها میتواند هرکدام از کاراکترهای [A-Za-z0-9_]، را مورد استفاده قرار دهند. به استثنای کلمات کلیدی زبان. عملگرهای + – * / جمع و تفریق و ضرب و تقسیم را به ترتیب نمایش میدهند. برای الحاق دو رشته آنها را به سادگی در کنار یکدیگر قرار میدهند. این اختیری است که استفاده کنید از فاصله در بین رشتهای که شامل ثابت میباشد. ولی شما نمیتوانید نام دو متغیر را بدون فاصله در کنار یکدیگر قرار دهید. رشتههای ثابت با "" محدود میشوند .عبارات نیاز به سمیکولن در انتها ندارند. در انتها توضیحات میتوانند با استفاده از # به عنوان اولین کاراکتر در خط به برنامه اضافه شوند.
تابع تعریف شده کاربر
کاربر تابع را در فرمتی شبیه به c تعریف میکند. تعریف تابع شامل کلید اصلی تابع نام تابع نام آرگومانها و بدنه تابع اینجا یک مثال از تابع آورده شده است:
function add_three (number, temp) { temp = number + 3 return temp }
این عبارت میتواند به صورت زیر احضار شود :
print add_three(36) # Outputs 39
تابع میتواند متغیرهایی در ناحیه محلی داشته باشد. نام آنها در انتهای لیست آرگومانها اضافه میشود. بنابراین هنگام فراخوانی تابع مقدار برای آنها باید حذف شود. این قرارداد است که کمی فضای خالی قبل از متغیرهای محلی در لیست آرگومانها اضافه کرد. به این ترتیب نشان داده میشود که پارامترها کجا تمام میشوند و متغیرهای محلی شروع میشوند.
مثالهای کاربردی
Hello world در اینجا یک برنامه hello world نوشته شده در awk موجود است:
BEGIN { print "Hello, world!" }
توجه داشته باشید که شما به یک عبارت صریح exit نیاز ندارید. تنها الگو BEGIN میباشد در هیچ خط دستور آرگومانها پردازش نمیشوند. چاپ خطهای بزرگتر از ۸۰ کاراکتر تمام خطوط طویل تر از ۸۰ کاراکتر را چاپ کن توجه داشته باشید که فعالیت پیش فرض چاپ خط جاری است.
length($0) > 80
چاپ شمارنده کلمات شمارنده کلمات در ورودی و چاپ خط، کلمه و کاراکترها
{ w += NF c += length + 1 } END { print NR, w, c }
به عنوان مثال هیچ الگویی برای خط اول برنامه وجود ندارد.هر خطی از خروجی منطبق با پیش فرض بنابرای فعالیت کاهش برای هرخط اجرا میشود.توجه کنید که w += NF کوتاهتر برای w = w + NF. جمع کردن کلمات آخر
{ s += $NF } END { print s + 0 }
S توسط ارزش عددی $NF توسعه داده شده که حرف آخر روی خط به عنوان زمینه جداکننده به وسیله awk تعریف شده به وسیله فضای خالی پیش فرض میباشد.NF شماره زمینهها در خط جاری میباشد . e.g. 4 از $۴ ارزش زمینه ۴ است . $NF ارزش آخرین زمینه در این خط صرف نظر از این که این خط دارای چه تعداد زمینه میباشد .یا اگر نسبت به خطوط اطراف بیشتر یا کمتر زمینه دارد . $ در حقیقت یک عملگر یگانی است که دارای بالاترین اولویت عملگرها میباشد.(اگر خط هیچ زمینهای نداشته باشد سپس NF 0, $0 تمام خط میباشد که در این مورد ممکن است بطور مجزا خالی از فضای سفید است.و بناباین ارزش عددی ۰ را داردبرای اختصار {} در این مثالها حذف شده اند. در انتهای ورودی الگوی منطبق با END است بنابراین s چاپ میشود.به هر حال تا زمانیکه هیچ خط ورودی وجود نداشته باشد.در این حالت هیچ مقداری به s انتساب داده نمیشود این به طور پیش فرض یک رشته خالی است.اضافه کردن ۰ به متغیرها یک اصطلاح Awk برای ناگزیر کردن از یک عدد به یک رشته ( تسلسل رشته خالی ناگزیر میکند از عدد به یک رشته eg )تو.جه داشته باشید .هیچ عملگری به الحاق رشتهها وجود ندارد.آنها فقط نزدیک جایگذاری میشوند .با ناگزیر بودن برنامه صفر را در ورودی خالی چاپ میکند .بدون آن یک خط خالی چاپ شده است.
انطباق محدوده ورودی در خطها
$ yes t | awk 'NR % 4 == 1, NR % 4 == 3 { printf "%6d %s\\n", NR, $0 }' | sed 7q 1 t 2 t 3 t 5 t 6 t 7 t 9 t $
دستور yes دائما این آرگومانها را روی خط چاپ میکند(با پیش فرض حرف 'y')در این مورد ما به دستور می گوییم که کلمه "Wikipedia" را چاپ کن .عبارت فعالیت هر خط شماره دار را چاپ میکند.تابعprintf از تابع استاندارد printf در C تقلید میکند.و مشابه دستور print که در بالا توضیح داده شد کار میکند.الگو برای انطباق به هر حال به شرح ذیل کار میکند. NR شماره رکوردها است. علامت خطوط ورودی که awk تا به حال خوانده است.شماره خط جاری شروع میشود از ۱ برای خط اول ورودی.%عملگر باقی مانده است . NR % 4 == 1 در ابتدا درست است.۵ ،۹و غره خطوط ورودی هستند . همانطور که NR % 4 == 3 درست است برای خط ۳،۷،۱۱و غیره خطوط ورودی .محدوده الگو اول نادرست است تا وقتی که قسمت اول منطبق شود .در خط اول وسپس به بالا رفتن ادامه میدهد تا وقتی که با قسمت دوم منطبق باشد .در خط سوم سپس نادرست میشود تا وقتی که قسمت اول با خط پنجم منطبق باشد .دستور Sed استفاده میشود برای چاپ ۷ خط اول.برای جلوگیری از دستور yes برای همیشه این همعنای head -7 اگر دستور اصلی موجود باشد. قسمت اول محدوده الگو بصورت دائمی درست میباشد e.g. 1. به عنوان محدوده شروع ورودی میتواند استفاده شود.به طور مشابه اگر قسمت دوم بطور دائمی نادرست باشد e.g. 0 محدوده ادامه پیدا میکند تا وقنتی که ورودی پایان یابد.
/^--cut here--$/, 0
چاپ کردن خطوط ورودی از خط اول منطبق بر عبارت با قاعده ^–cut here–$ که این یک خط شامل فقط یک عبارت "—cut here—" تا به انتها است. محاسبه تکرار کلمه برای تکرار کلمه از آرایه شرکت پذیر استفاده میشود
BEGIN { FS="[^a-zA-Z]+" } { for (i=1; i<=NF; i++) words[tolower($i)]++ } END { for (i in words) print i, words[i] }
بلوک BEGIN زمینه جدا کننده را به هر دسته از کاراکترهای غیر الفبایی نسبت میدهد.توجه داشته باشید که جدا کننده میتواند عبارت با قاعده باشد .بعد از آن ما به یک فعالیت محض می رسیم.که فعالیت را در هر خط ورودی انجام میدهد.در این مورد ما برای هر زمینه در روی خط یک واحد به شماره دوره کلمه اضافه می کنیم.ابتدا کلمه را به حروف کوچک تبدیل میکند ظاهر میشود در انتها، در پایان بلوک، ما کلمه را با تعداد تکرارش چاپ می کنیم:
for (i in words)
ایجاد حلقه برای حرکت در میان کلمات آرایه .تنظیم کردن i برای هر زیر نویس از آرایهای نسبت به بسیاری از زبانا متفاوت است که حلقه در میان کلمات آرایه حرکت کند.این به این معنا است که چاپ کردن کلمه با هر شمارندهای به سادهترین راه ممکن است. Tolower یک جمع در یک حقیقت Awk ساخته شده قبل از منتشر شدن کتاب است .
انطباق الگو از خط دستور
این برنامه به چندین راه میتواند معرفی شود.اولین راه استفاده از Bourne shell برای ایجاد shell script که هر چیزی را انجام میدهد.این کوتاه شده این متد است.
$ cat grepinawk pattern=$1 shift awk '/'$pattern'/ { print FILENAME ":" $0 }' $* $
الگو $ در دستور awk توسط گیومه محافظت نمیشود.یک الگو به خودی خود در راه عادی چک میکند تا ببند با تمام خطهای ($۰) منطبق است .نام فایل شامل نام فایل جاری است.awk عملگر جداگانهای برای الحاق ندارد.دو رشته مجار با هم متصل میشوند. $۰ بدون تغییر ورودی به خطوط اصلی تغییر پیدا میکند .آنها راههای متناوب برای نوشتن این هستند .این shell script دسترسی دارد به محیط به صورت مستقیم از داخل awk.
$ cat grepinawk pattern=$1 shift awk '$0 ~ ENVIRON[\"pattern\"] { print FILENAME ":" $0 }' $* $
این shell script که برای دورزدن استفاده میشود.یک آرایه در ورژن جدیدتر از یک awk درست بعد از این که کتاب منتشر شد معرفی میشود. subscript of ENVIRON برای احاطه کردن نام یک محیط متغیری میباشد نتیجه آن مقدار متغیر میباشد .و این شبیه تابع getenv در کتابخانههای متنوع استاندارد و POSIX میباشد . shell script محیط متغیری الگو شامل آرگومان اول را درست میکند.سپس آرگومان را می اندازد و Awk الگو را در هر فایلی جستجو میکند.~ چک میکند که عملوند سمت چپ با عملوند سمت راست منطبق باشد!~ به صورت برعکس.توجه کنید که عبارت با قاعده فقط یک رشته است و میتواند به عنوان یک متغیر ذخیره شود .راه دیگر استفاده از انتساب متغیرها ی دستور–خط میباشد در این مورد آرگومان awk میتواند به عنوان انتساب به متغیرها داده شود.
$ cat grepinawk pattern=$1 shift awk '$0 ~ pattern { print FILENAME ":" $0 }' "pattern=$pattern" $* $
در انتها نوشته میشود در awk اصل بدون کمک گرفتن از shell یا بدون دانستن زیاد در مورد اجرای awk script .(به عنوان انتساب در خط فرمان انجام میشود .)ولی به اندازه یک بیت درازا دارد.
BEGIN { pattern = ARGV[1] for (i = 1; i < ARGC; i++) # remove first argument ARGV[i] = ARGV[i + 1] ARGC—if (ARGC == 1) { # the pattern was the only thing, so force read from standard input (used by book) ARGC = 2 ARGV[1] = "-" } } $0 ~ pattern { print FILENAME ":" $0 }
BEGIN خیلی ضروری برای استخراج آرگومان اول نمیباشد، ولی اغلب برای جلوگیری از ترجمه شدن به عنوان نام فایل بعد از BEGIN بلوک بسته میشودARGC شماره آرگومانه میباشد که اغلب بزرگتر از ۱ میباشند.به عنوان مثال ARGV[0] نام دستوری است که اجرا میکند بیشتر اوقات رشته "awk".اغلب توجه کنید که ARGV[ARGC] یک رشته خالی است"".# ابتدای یک توضیح است که تا پایان خط ادامه دارد.توجه کنید به بلوک if awk، قبل از این که اجرا کند دستور را چک میکند که ببیند از ورودی استاندارد خوانده شده است.این بدان معنا است که:
awk 'prog'
کارها فقط به خاطر این حقیقت که هیچ نام فایلی وجود نداردقبل از اجرای برنامه چک میشود.اگر شما به طور واضح تنظیم کنیدARGC به ۱ بنابراین هیچ آرگومانی وجود ندارد.awkبه طور ساده و مختصر خواهد شد به خاطر اینکه فکر میکند هیچ نام فایلی ورودی دیگری وجود ندارد.بنابراین شما نیاز دارید که به طور واضح بگویید با یک نام فایل ویژه از یک ورودی استاندارد می خوانید
Self-contained AWK scripts
به عنوان مثال با خیلی از زبانهای برنامه نویسی دیگر خود شمولی AWK script میتواند با سازنده برای استفاده کردن از so-called " shebang" syntax به عنوان مثال دستور UNIX فراخوانی میکند hello.awk که چاپ میکند رشته "Hello, world!" که جزوی از ساختمانی است که وسیله اسم فایل ساخته میشود hello.awkکه شامل خط زیر میباشد.
#!/usr/bin/awk -f BEGIN { print "Hello, world!" }
-f به awk میگوید یک آرگومان که فایل را دنبال میکند تا برنامه awk از آن بخواند ، که به وسیله shell وقتی که اجرا میشود جایگزین میشود.
ورژنها و پیاده سازی AWK
AWK به طور کلی در سال ۱۹۷۷ نوشته شد و با ورژن ۷ Unix توزیع شد. در سال ۱۹۸۵ نویسندههای آن به وسیله اضافه کردن توابع user-defined شروع به گسترش زبان کردند.در کتاب AWK Programming Language زبان توضیح داده شد و در سال ۱۹۸۸ منتشر و پیاده سازی شد وبا UNIX System V عرضه شد.برای پرهیز از اشتباه شدن با ورژنهای قدیمی ناسازگار بعضی وقتها این ورژن به عنوان "new awk" یا nawk شناخته میشد.این پیاده سازی تحت لیسانس free software license در ۱۹۹۶ عرضه شد وهمچنان توسط Brian Kernighan نگهداری میشود . BWK awk رجوع میکند به ورژن Brian W. Kernighan .که دوبله میکند "One True AWK" بخاطر استفاده کردن از اصطلاح در وابسته سازی با کتاب که به طور کلی زبان را توصیف میکند. و حقیقت این است که Kernighan یکی از نویسندگان اصلی awk است . FreeBSD به این ورژن مراجعه میکند به عنوان مثال one-true-awk.این ورژن اغلب ویژگی هایش در این کتاب نبود.از قبیل tolower وENVIRON که در بالا توضیح داده شده است. gawk (GNU awk) یک نرمافزار آزاد دیگر است که پیاده سازی شد و تنها پیاده سازی است که تلاش جدی در انجام داده i18n دارد.و اغلب به کاربر اجازه میدهد که تابعیت برنامه خود را با کتابخانههای اشتراکی نوشته شده توسط کاربر توسعه دهد.که قبل از پیاده سازی اصلی نوشته شد که به صورت آزاد موجود بود.و هنوز به طور گسترده استفاده میشود.خیلی از نسخههای Linux با این ورژن اخیرgawk آمدند وgawk به طور وسیعی به عنوان de-facto پیاده سازی استاندارد در دنیای Linux شناخته شد. gawk ورژن ۳ شامل awk در FreeBSD تا پیش از ورژن ۵ بود.ورژنهای بعدی FreeBSD از BWK awk برای جلوگیری از GPL استفاده کردند.محدود کردن بیشتر (در این جهت که GPL لیسانس کد نمیتواند باعث اختصاصی شدن یک نرمافزار شود.)لیسانس از BSD لیسانس. xgawk یک پروژه SourceForge که برا ساس gawk است.که gawk را با کتابخانههای قابل بارگذاری پویا گسترش داده است. mawk یک پیاده سازی AWK مرجع است که به وسیله Mike Brennan و براساس مفسر بایت کد میباشد . ورژن قدیمی Unix از قبیل UNIX/32V شامل awkcc که تبدیل کننده AWK به C بود. Kernighan برنامهای برای تبدیل awk به C++ نوشت ولی این حالت شناخته شده نیست. awka (کسی که با انتها در نوشتن در بالای برنامه mawk مواجه شد .)که یک مترجم دیگر از awk به C میباشد .وقتی که کامپایل میشود شامل نویسنده libawka.a میباشد نتیجه اجرایی به طور اهم براساس تست مقایسه نویسنده با سایر ورژنهای awk, perl یا tcl میباشد. scripts کوچک میتوانند به برنامههای ۱۶۰-۱۷۰ kB تبدیل شوند. Thompson AWK یا TAWK یک کامپایلر AWKبرای Solaris , DOS, OS/2، و Windows که توسط Thompson Automation Software قبلا فروخته شد.(که فعالیتهایش را متوقف میکند). Jawk یک SourceForge پروژه است که AWK را در Java پیاده سازی میکند. ویژگیهایی به زبان اضافه شد تا دسترسی به ویژگیهای Java در داخل AWK را فراهم کند. BusyBox شامل پروندههای پراکنده که ظاهر میشود تا کامل کند، نوشته شده به وسیله Dmitry Zakharov .این یک پیاده سازی کوتاه و مناسب برای سیستمهای جاسازی شده میباشد.