| NAWK(1) | General Commands Manual | NAWK(1) |
نام (NAME)
nawk - زبان پیمایش و پردازش متن مبتنی بر الگو
خلاصه دستور (SYNOPSIS)
nawk [ -F fs | --csv ] [ -v var=value ] [ 'prog' | -f progfile ] [ file ... ]
توضیحات (DESCRIPTION)
دستور Nawk هر file ورودی را برای یافتن خطوطی که با هر یک از مجموعهای از الگوهای مشخصشده به صورت صریح در prog یا در یک یا چند فایل مشخصشده با -f progfile مطابقت داشته باشند، پیمایش میکند. همراه با هر الگو میتواند یک عمل مرتبط وجود داشته باشد که با منطبق شدن خطی از یک file با الگو اجرا خواهد شد. هر خط با بخش الگوی هر دستور الگو-عمل تطبیق داده میشود؛ عمل مرتبط برای هر الگوی منطبق اجرا میگردد. نام فایل - نشاندهنده ورودی استاندارد است. هر file به فرم var=value به عنوان یک مقداردهی و انتساب در نظر گرفته میشود، نه یک نام فایل، و در همان زمانی اجرا میشود که اگر نام فایل بود باز میشد. گزینه -v همراه با var=value انتسابی است که پیش از اجرای prog انجام میشود؛ هر تعداد از گزینههای -v میتوانند مشخص شوند. گزینه -F fs جداکننده فیلدهای ورودی را به عبارت باقاعده fs تعیین میکند. گزینه --csv باعث میشود که awk رکوردها را با استفاده از قالب استاندارد مقادیر جداشده با کاما (CSV) پردازش کند.
یک خط ورودی معمولاً از فیلدهایی تشکیل شده است که با فاصله یا با عبارت باقاعده FS از یکدیگر جدا شدهاند. این فیلدها با $1، $2، ... نشان داده میشوند، در حالی که $0 به کل خط اشاره دارد. اگر FS تهی باشد، خط ورودی به ازای هر نویسه به یک فیلد تفکیک میشود.
یک دستور الگو-عمل دارای فرم زیر است:
- pattern { action }
نبود { action } به معنای چاپ خط است؛ نبود الگو همیشه منطبق در نظر گرفته میشود. دستورهای الگو-عمل با خط جدید یا نقطه-ویرگول از هم جدا میشوند.
یک عمل، توالیای از گزارهها است. یک گزاره میتواند یکی از موارد زیر باشد:
if( expression ) statement [ else statement ] while( expression ) statement for( expression ; expression ; expression ) statement for( var in array ) statement do statement while( expression ) break continue { [ statement ... ] } expression # معمولاً var = expression print [ expression-list ] [ > expression ] printf format [ , expression-list ] [ > expression ] return [ expression ] next # نادیده گرفتن الگوهای باقیمانده روی این خط ورودی nextfile # نادیده گرفتن ادامه این فایل و رفتن به فایل بعدی از ابتدا delete array[ expression ] # حذف یک عنصر آرایه delete array # حذف تمامی عناصر آرایه exit [ expression ] # خروج فوری؛ وضعیت خروج expression است
گزارهها با نقطه-ویرگول، خط جدید یا آکوالاد بسته خاتمه مییابند. یک expression-list خالی نشاندهنده $0 است. ثابتهای رشتهای درون " " قرار میگیرند، و نویسههای گریز رایج در C در آنها شناسایی میشوند. عبارات بسته به کاربرد، مقادیر رشتهای یا عددی به خود میگیرند، و با استفاده از عملگرهای + - * / % ^ (بهتوانرسانی) و الحاق (مشخصشده با فاصله) ساخته میشوند. عملگرهای ! ++ -- += -= *= /= %= ^= > >= < <= == != ?: نیز در عبارات در دسترس هستند. متغیرها میتوانند مقادیر عددی یا رشتهای ساده، عناصر آرایه (نشاندادهشده با x[i]) یا فیلدها باشند. متغیرها با رشته تهی مقداردهی اولیه میشوند. اندیسهای آرایه میتوانند هر رشتهای باشند و لزوماً عددی نیستند؛ این قابلیت امکان ایجاد نوعی حافظه انتسابی (آرایه انجمنی) را فراهم میآورد. اندیسهای چندگانه مانند [i,j,k] مجاز هستند؛ اجزای آنها به هم متصل شده و با مقدار SUBSEP از هم جدا میشوند.
گزاره print آرگومانهای خود را در خروجی استاندارد چاپ میکند (یا در یک فایل در صورتی که > file یا >> file حضور داشته باشد، یا روی یک پایپ اگر | cmd مشخص شده باشد)، که با جداکننده فیلد خروجی فعلی از هم جدا شده و با جداکننده رکورد خروجی خاتمه مییابند. file و cmd میتوانند نامهای صریح یا عبارات داخل پرانتز باشند؛ مقادیر رشتهای یکسان در گزارههای مختلف نشاندهنده همان فایل بازشده یکسان هستند. گزاره printf فهرست عبارات خود را مطابق با format قالببندی میکند (به printf(3) مراجعه کنید). تابع توکار close(expr) فایل یا پایپ expr را میبندد. تابع توکار fflush(expr) هرگونه خروجی بافرشده را برای فایل یا پایپ expr تخلیه میکند.
توابع ریاضی atan2، cos، exp، log، sin و sqrt به صورت توکار در دسترس هستند. سایر توابع توکار:
- length([v])
- طول آرگومان آن به صورت یک رشته، تعداد عناصر موجود در آرایه در صورت ارائه یک آرگومان آرایهای، یا در صورت عدم ارائه آرگومان، طول $0 .
- rand()
- یک عدد تصادفی در بازه [0,1).
- srand([s])
- تنظیم دانه برای rand و بازگرداندن دانه قبلی.
- int(x)
- کوتاه کردن به یک مقدار صحیح.
- substr(s, m [, n])
- زیررشته n-نویسهای از s که از موقعیت m (با شروع از ۱) آغاز میشود. در صورت عدم مشخص شدن n، از باقیمانده رشته استفاده میشود.
- index(s, t)
- موقعیت وقوع رشته t در s ، یا 0 در صورت عدم وقوع.
- match(s, r)
- موقعیت وقوع عبارت باقاعده r در s ، یا 0 در صورت عدم وقوع. متغیرهای RSTART و RLENGTH روی موقعیت و طول رشته منطبقشده تنظیم میشوند.
- split(s, a [, fs])
- رشته s را به عناصر آرایه a[1]، a[2]، ...، a[n] تقسیم میکند و مقدار n را برمیگرداند. جداسازی با عبارت باقاعده fs یا با جداکننده فیلد FS (در صورتی که fs داده نشده باشد) انجام میگیرد. یک رشته خالی به عنوان جداکننده فیلد، رشته را به ازای هر نویسه به یک عنصر آرایه تقسیم میکند.
- sub(r, t [, s])
- رشته t را جایگزین اولین رخداد عبارت باقاعده r در رشته s میکند. اگر s داده نشود، از $0 استفاده خواهد شد.
- gsub(r, t [, s])
- مشابه با sub است، با این تفاوت که تمام رخدادهای عبارت باقاعده جایگزین میشوند؛ sub و gsub تعداد جایگزینیهای انجامشده را برمیگردانند.
- sprintf(fmt, expr, ...)
- رشته حاصل از قالببندی expr ... مطابق با قالب fmt در printf(3).
- system(cmd)
- دستور cmd را اجرا کرده و وضعیت خروج آن را برمیگرداند. این مقدار در صورت بروز خطا -1 خواهد بود، در صورت خروج عادی وضعیت خروج cmd، در صورت بسته شدن با سیگنال مقدار 256 + sig (که در آن sig شماره سیگنال کشنده است)، یا 512 + sig در صورت ایجاد core dump.
- tolower(str)
- یک رونوشت از str را برمیگرداند که تمام نویسههای بزرگ آن به معادلهای کوچک مربوطهشان تبدیل شدهاند.
- toupper(str)
- یک رونوشت از str را برمیگرداند که تمام نویسههای کوچک آن به معادلهای بزرگ مربوطهشان تبدیل شدهاند.
«تابع» getline مقدار $0 را روی رکورد ورودی بعدی از فایل ورودی جاری قرار میدهد؛ getline < file مقدار $0 را روی رکورد بعدی از file قرار میدهد. getline x به جای آن، متغیر x را مقداردهی میکند. در نهایت، cmd | getline خروجی cmd را به getline هدایت میکند؛ هر فراخوانی getline خط بعدی خروجی از cmd را برمیگرداند. در همه موارد، getline در صورت ورودی موفقیتآمیز مقدار 1، برای پایان فایل مقدار 0، و در صورت بروز خطا مقدار -1 را برمیگرداند.
الگوها ترکیبات بولی اختیاری (با ! || &&) از عبارات باقاعده و عبارات رابطهای هستند. عبارات باقاعده مانند egrep هستند؛ به grep(1) مراجعه کنید. عبارات باقاعده منفرد در یک الگو برای کل خط اعمال میشوند. عبارات باقاعده میتوانند در عبارات رابطهای نیز حضور داشته باشند، با استفاده از عملگرهای ~ و !~. عبارت /re/ یک عبارت باقاعده ثابت است؛ هر رشتهای (ثابت یا متغیر) میتواند به عنوان یک عبارت باقاعده استفاده شود، به جز در جایگاه یک عبارت باقاعده منفرد در یک الگو.
یک الگو میتواند شامل دو الگو باشد که با کاما از هم جدا شدهاند؛ در این حالت، عمل برای تمام خطوط از زمان وقوع الگوی اول تا وقوع الگوی دوم (شامل هر دو) انجام میشود.
یک عبارت رابطهای یکی از موارد زیر است:
- expression matchop regular-expression
expression relop expression
expression in array-name
(expr,expr,...) in array-name
که در آن relop هر یک از شش عملگر رابطهای در C است، و matchop یا ~ (منطبق است) یا !~ (منطبق نیست) است. یک گزاره شرطی یک عبارت حسابی، یک عبارت رابطهای، یا یک ترکیب بولی از اینها است.
الگوهای ویژه BEGIN و END میتوانند برای در دست گرفتن کنترل پیش از خواندن اولین خط ورودی و پس از آخرین خط استفاده شوند. BEGIN و END با دیگر الگوها ترکیب نمیشوند. آنها میتوانند چندین بار در یک برنامه ظاهر شوند و به همان ترتیبی که توسط nawk خوانده میشوند، اجرا گردند.
نامهای متغیر با معانی خاص:
- ARGC
- تعداد آرگومانها، قابل انتساب.
- ARGV
- آرایه آرگومانها، قابل انتساب؛ اعضای غیرتهی به عنوان نام فایلها در نظر گرفته میشوند.
- CONVFMT
- قالب تبدیل مورد استفاده هنگام تبدیل اعداد (پیشفرض %.6g).
- ENVIRON
- آرایه متغیرهای محیطی؛ اندیسها نام متغیرها هستند.
- FILENAME
- نام فایل ورودی فعلی.
- FNR
- شماره ترتیبی رکورد جاری در فایل فعلی.
- FS
- عبارت باقاعده مورد استفاده برای جداسازی فیلدها؛ همچنین با گزینه -Ffs قابل تنظیم است.
- NF
- تعداد فیلدها در رکورد جاری.
- NR
- شماره ترتیبی رکورد جاری.
- OFMT
- قالب خروجی برای اعداد (پیشفرض %.6g).
- OFS
- جداکننده فیلد خروجی (پیشفرض فاصله).
- ORS
- جداکننده رکورد خروجی (پیشفرض خط جدید).
- RLENGTH
- طول رشته منطبقشده توسط match.
- RS
- جداکننده رکورد ورودی (پیشفرض خط جدید). در صورت خالی بودن، خطوط خالی رکوردها را از هم جدا میکنند. اگر طول آن بیش از یک نویسه باشد، RS به عنوان یک عبارت باقاعده در نظر گرفته میشود و رکوردها با متنی که با این عبارت تطبیق یابد جدا میشوند.
- RSTART
- موقعیت شروع رشته تطبیقیافته توسط match.
- SUBSEP
- جداکننده اندیسهای چندگانه (پیشفرض 034).
توابع را میتوان (در جایگاه دستور الگو-عمل) به این شکل تعریف کرد:
- function foo(a, b, c) { ... }
پارامترها در صورتی که اسکالر باشند با مقدار (by value) و در صورتی که نام آرایه باشند با ارجاع (by reference) ارسال میشوند؛ توابع میتوانند به صورت بازگشتی فراخوانی شوند. پارامترها برای تابع محلی هستند؛ تمام متغیرهای دیگر سراسری میباشند. بنابراین میتوان متغیرهای محلی را با تعیین پارامترهای اضافی در تعریف تابع ایجاد کرد.
متغیرهای محیطی (ENVIRONMENT VARIABLES)
اگر POSIXLY_CORRECT در محیط تنظیم شده باشد، awk از قوانین POSIX برای sub و gsub با توجه به بکاسلشها و علامتهای آمپرسند پیاپی پیروی میکند.
مثالها (EXAMPLES)
length($0) > 72
چاپ خطوط طولانیتر از ۷۲ نویسه.
{ print $2, $1 }
چاپ دو فیلد اول با ترتیب معکوس.
BEGIN { FS = ",[ \t]*|[ \t]+" }
{ print $2, $1 }
- مشابه مثال قبل، با فیلدهای ورودی که با کاما و/یا فاصله و تب جدا شدهاند.
{ s += $1 }
END { print "sum is", s, " average is", s/NR }
- جمع زدن مقادیر ستون اول، و چاپ مجموع و میانگین.
/start/, /stop/
چاپ تمامی خطوط بین جفتهای start/stop.
BEGIN { # Simulate echo(1)
for (i = 1; i < ARGC; i++) printf "%s ", ARGV[i]
printf "\n"
exit }
همچنین ببینید (SEE ALSO)
grep(1), lex(1), sed(1)
A. V. Aho, B. W. Kernighan, P. J. Weinberger, The AWK Programming Language,
Second Edition, Addison-Wesley, 2024. ISBN 978-0-13-826972-2,
0-13-826972-6.
اشکالات (BUGS)
هیچ تبدیل صریحی بین اعداد و رشتهها وجود ندارد. برای وادار کردن رفتار با یک عبارت به عنوان عدد، مقدار 0 را به آن اضافه کنید؛ برای وادار کردن رفتار با آن به عنوان یک رشته، "" را با آن الحاق نمایید.
قوانین محدوده دسترسی (scope) برای متغیرها در توابع دارای اشکال است؛ نحو نوشتاری آن نیز حتی بدتر است.
انتظار میرود ورودی دارای کدگذاری UTF-8 باشد. سایر مجموعهنویسههای چندبایتی پشتیبانی نمیشوند. با این حال، در لوکالهای هشت بیتی، awk با هر بایت ورودی به عنوان یک نویسه جداگانه رفتار میکند.
مقادیر ممیز شناور نامتعارف (UNUSUAL FLOATING-POINT VALUES)
دستور Awk پیش از آنکه محاسبات IEEE 754 مقادیر Not-A-Number (NaN) و بینهایت (Infinity) را تعریف کند طراحی شد؛ مقادیری که توسط تمام سختافزارهای ممیز شناور مدرن پشتیبانی میشوند.
به دلیل اینکه awk از توابع strtod(3) و atof(3) برای تبدیل مقادیر رشتهای به مقادیر ممیز شناور با دقت مضاعف استفاده میکند، کتابخانههای مدرن C نیز رشتههایی را که با inf و nan شروع میشوند، به ترتیب به مقادیر بینهایت و NaN تبدیل میکنند. این امر منجر به نتایج عجیبی میشد، مانند این مورد:
echo nancy | awk '{ print $1 + 0 }'
که به جای صفر، مقدار nan را چاپ میکرد.
اکنون Awk از GNU AWK پیروی میکند و پیش از تلاش برای تبدیل رشتهها به اعداد، مقادیر رشتهای را به صورت زیر پیشفیلتر میکند:
- مقادیر هگزادسیمال
- مقادیر هگزادسیمال (که از استاندارد C99 مجاز شدهاند)، همانطور که پیش از C99 بود به صفر تبدیل میشوند.
- مقادیر NaN
- دو رشته +nan و -nan (بدون حساسیت به حروف کوچک و بزرگ) به NaN تبدیل میشوند؛ هیچ رشته دیگری اینگونه نیست. (NaNها میتوانند علامت داشته باشند.)
- مقادیر بینهایت
- دو رشته +inf و -inf (بدون حساسیت به حروف کوچک و بزرگ) به ترتیب به بینهایت مثبت و منفی تبدیل میشوند. هیچ رشته دیگری اینگونه نیست.