آشنایی با دستور awk در لینوکس و نحوه استفاده از آن
awk یک ابزار اسکریپت نویسی است که به کاربران لینوکس اجازه می دهد از متغیرها، توابع عددی و رشته ای و عملگرهای منطقی برای پردازش فایل های متنی استفاده کنند. با دستور awk در لینوکس می توانید کارهای مربوط به دستکاری داده ها از جمله جستجوی الگو یا متن در یک فایل متنی را انجام دهید.
دستور awk این امکان را به کاربران برنامه نویس می دهد که با یک سینتکس ساده و آپشن های کاربردی، برنامه های کوچکی را ایجاد کنند و از آنها برای اسکن و پردازش الگوهای متنی استفاده کنند.
کاربردهای اصلی دستور awk در لینوکس
- ایجاد اسکریپت های تک خطی
- تولید گزارشات قالب بندی شده
- پردازش فایل های متنی مثل CSV
- استخراج ستون های خاص از فایل های متنی
- انجام محاسبات ریاضی روی داده ها
- مقایسه و شرط گذاری روی داده ها
- پردازش خروجی دستورات
- گزارش گیری از اسکریپت های شل
- اتوماسیون و اسکریپت نویسی
- …
دستور awk چگونه کار می کند؟
این دستور بر اساس روند خواندن ورودی، اعمال الگوها و اجرای عملیات کار می کند. به این صورت که ورودی را به صورت خط به خط می خواند، هر خط را به فیلد های مجزا تقسیم می کند و سپس بر اساس الگوی تعریف شده، عملیات موردنظر را اجرا می کند.
در ادامه به بررسی مثال های کاربردی می پردازیم که درک عمیق تری از طرز کار این ابزار به شما خواهد داد.
پیش نیازهای استفاده از دستور awk در لینوکس
- دسترسی به سیستم یا سرور لینوکس
- دسترسی به ترمینال
- نصب بودن دستور awk
این دستور به طور پیش فرض در اکثر توزیع های لینوکس نصب است. محض احتیاط بهتر است با دستور زیر بررسی کنید که این دستور در سیستم شما نصب است یا نه:
awk –version
اگر در خروجی این دستور، شماره نسخه دستور awk را ندیدید، یعنی دستور awk در سیستم شما نصب نیست و برای استفاده از آن، ابتدا باید آن را نصب کنید:
دستور نصب awk در توزیع های مبتنی بر دبیان مثل اوبونتو
sudo apt install gawk
دستور نصب awk در توزیع های مبتنی بر redhat مثل centos و فدورا
sudo yum install gawk
یا
sudo dnf install gawk
دستور نصب awk در آرچ لینوکس
sudo pacman -S gawk
دستور نصب awk در OpenSUSE
sudo zypper install gawk
بعد از اینکه از نصب این ابزار در سیستم خود مطمئن شدید، می توانید شروع به استفاده از آن کنید.
در صورت نیاز به یک سرور لینوکس قدرتمند و حرفه ای جهت استفاده از ابزارهای پرکاربردی مثل awk در پروژه های پیشرفته خود می توانید به صفحه خرید سرور مجازی لینوکس مراجعه کنید و پلن ایده آل خود را سفارش دهید.
سینتکس دستور awk در لینوکس
سینتکس پایه دستور awk به صورت زیر است:
awk 'pattern{action}' filename
با اینکه هدف اصلی این دستور هندل کردن الگوها و اجرای عملیات مرتبط با آنها است ولی آپشن هایی هم وجود دارند که برای تغییر رفتار این دستور استفاده می شوند.
آپشن های اصلی دستور awk
آپشن | کاربرد |
v- | تعریف متغیرهای دلخواه |
f- | اجرای اسکریپت های awk با استفاده از فایل |
W lint- | نمایش هشدارها و خطاهای احتمالی موقع اجرای اسکریپت |
W compat- | اعمال سازگاری با نسخه های قدیمی |
version– | نمایش نسخه دستور |
در صورت نیاز به کسب اطلاعات بیشتر در مورد این دستور می توانید از دو دستور زیر کمک بگیرید:
man awk
awk -help
مثال های کاربردی از دستور awk در لینوکس
با تست این مثال ها به طور کامل با طرز استفاده از دستور awk آشنا خواهید شد.
پرینت یک پیام متنی در خروجی
ساده ترین و ابتدایی ترین کاربرد دستور awk این است که مثل دستور echo می تواند پیام موردنظر شما را در خروجی چاپ کند:
awk '{print "Welcome to awk command tutorial "}'
استفاده از متغیرهای داخلی awk
$0
انتخاب کل ستون های یک خط
$1
انتخاب ستون اول
$2
انتخاب ستون دوم
n$
انتخاب ستون nام
NR
این متغیر شماره خطوط را نشان می دهد.
awk '{print NR,$0}' file.txt
1 ajay manager account 45000
2 sunil clerk account 25000
3 varun manager sales 50000
4 amit manager account 47000
5 tarun peon sales 15000
6 deepak clerk sales 23000
7 sunil peon sales 13000
8 satvik director purchase 80000
NF
این متغیر فیلد یا ستون آخر را نشان می دهد.
awk '{print $1,$NF}' file.txt
ajay 45000
sunil 25000
varun 50000
amit 47000
tarun 15000
deepak 23000
sunil 13000
satvik 80000
FS
تقسیم بندی فیلدها بر اساس یک کاراکتر خاص
RS
تقسیم بندی ردیف ها بر اساس یک کاراکتر خاص
OFS
تقسیم بندی فیلد های خروجی
ORS
تقسیم بندی ردیف های خروجی
کلمات کلیدی BEGIN و END هم برای انجام عملیات قبل و بعد از پردازش خط های ورودی استفاده می شوند که کاملاً اختیاری هستند.
یک مثال از BEGIN)
awk 'BEGIN { print "شروع پردازش" } { print $0 }' file.txt
قبل از پرینت ستون اول، یک پیام تحت عنوان شروع پردازش چاپ می شود.
یک مثال از END)
awk '{ sum += $1 } END { print "جمع اعداد: ", sum }' file.txt
ابتدا مقادیر مربوط به ستون اول محاسبه می شود و در آخر، پیام جمع اعداد به همراه جمع حاصل در خروجی نمایش داده می شود.
نمایش محتوای یک فایل متنی
برای این دستور نیازی به وارد کردن هیچ الگویی نیست و کافیست print را به عنوان action وارد کنید:
awk '{print}' file.txt
با توجه به این که هیچ الگویی در این دستور لحاظ نشده است، دستور awk عملیات print را روی تمام خط های این فایل اعمال می کند و همه آنها را در خروجی پرینت می کند.
حالا اگر می خواهید ستون های خاصی از این متن را مشاهده کنید، می توانید شماره ستون را به صورت زیر در دستور لحاظ کنید:
ستون اول
awk '{print $1}' file.txt
ستون اول و چهارم
awk '{print $1 $4}' file.txt
ستون آخر
awk '{print $NF}' file.txt
برای اینکه خطوط خاصی از یک ستون را در خروجی ببینید، می توانید دستور awk و head یا tail را پایپ کنید.
به عنوان مثال برای مشاهده دو خط اول مربوط به ستون سوم، کافیست دستور زیر را اجرا کنید:
awk '{print $1}' file.txt | head -2
حتی می توانید پرینت را سفارشی سازی کنید تا خروجی را برای خود قابل درک تر کنید. به عنوان مثال NR را که شماره خطوط یا ردیف ها را نشان می دهد، به صورت زیر در دستور پرینت لحاظ کنید تا خروجی قشنگ تری داشته باشد:
awk 'print NR "- " $1' file.txt
این دستور خروجی را به این شکل به شما نشان می دهد:
1 - Ubuntu
2 - CentOs
3 – Fedora
4 - Debian
نمایش محتوای یک فایل بر اساس الگوی عبارت منظم
اگر الگوی خاصی را در نظر دارید و می خواهید خطوطی که با این الگو مطابقت دارند، در خروجی نمایش داده شوند می توانید این الگو را به صورت زیر در دستور awk لحاظ کنید:
awk '/pattern/' file.txt
حالا بستگی به هدف موردنظر شما دارد که از چه الگویی استفاده کنید. ما در این بخش چند الگو را بررسی می کنیم:
۱) نمایش خطوط حاوی کلمه linux
awk '/linux/' file.txt
۲) نمایش خطوطی که با یک کاراکتر خاص شروع می شوند (مثلاً O)
awk '/^O/' file.txt
۳) نمایش خطوطی که با یک کاراکتر خاص تمام می شوند (مثلاً t)
awk '/t$/' file.txt
۴) نمایش دو ستون اول و دوم خطوط حاوی IT
awk '/IT/ {print $1, $2}' file.txt
۵) نمایش دو ستون اول و دوم خطوط حاوی IT و software
awk '/IT/, /software/ {print $1, $2}' file.txt
استفاده از عملگرهای مقایسه ای در دستور awk
دستور awk این آزادی را به شما می دهد که عملگرهای مقایسه ای (<, <=, ==, !=, >= و >) را هم وارد عمل کنید و بسته به نیاز خود، خطوط موجود در فایل موردنظر را فیلتر کنید.
به عنوان مثال اگر فایلی دارید که حاوی مشخصات کارکنان است، می توانید دستور awk را طوری بنویسید که فقط اطلاعات کارکنان ۴۰ سال به پایین را پرینت کند:
awk '$3 < 40 {print}' file.txt
یا اگر می خواهید خطوطی که طول آنها کمتر از ۲۰ است را ببینید، می توانید دستور awk را به صورت زیر اجرا کنید:
awk 'length($0) > 20' file.txt
حالا بیایید یک سطح دیگری از عملگرهای مقایسه ای را بررسی کنیم و آن را با دستورات شرطی ترکیب کنیم.
فرض کنید یک فایل متنی دارید که می خواهید ببینید ستون اول کدام ردیف ها زوج و کدام یک فرد است.
باید دستور if را با عملگرهای مقایسه ای ترکیب کنید:
awk '{ if ($1 % 2 == 0) print $1, "is even"; else print $1, "is odd"; }' file.txt
این دستور ستون اول آیتم های موجود در فایل را یکی یکی بررسی می کند و عدد را به همراه پیام زوج (even) یا فرد (odd) چاپ می کند.
استفاده از عملگرهای منطقی در دستور awk
عملگرهای منطقی برای بررسی و ارزیابی شرایط مختلف قابل استفاده هستند و به کمک آنها می توانید به اسکریپت موردنظر خود پر و بال دهید.
در کل، ۳ عملگر منطقی وجود دارد:
&& (AND منطقی)
|| (OR منطقی)
! (NOT منطقی)
به عنوان مثال، اگر بخواهید خطوطی که ستون سوم آنها بیشتر از ۱۰ و (&&) ستون چهارم آنها کمتر از ۲۰ هستند را ببینید، می توانید از عملگر && استفاده کنید.
awk '$3 > 10 && $4 < 20 {print $1, $2}' file.txt
یا مثلاً اگر فایلی دارید که حاوی لیست نمرات دانش آموزان است و می خواهید بررسی کنید که وضعیت این دانش آموزان در دو درس (ستون ۲ و ۳) چگونه است، می توانید از دستور زیر استفاده کنید:
awk '
{
if (($2 > 80 && $3 > 80) || ($2 < 75 && $3 < 75)) {
print $1 " باید بررسی شود"
} else {
print $1 " قابل قبول است"
}
}' students.txt
استفاده از حلقه ها در دستور awk
شما با استفاده از دستور awk می توانید سورس کد موردنظر را در همان فضای ترمینال اجرا کنید. البته نه کدهای طولانی که برای اهداف بزرگی توسعه یافته اند!
به عنوان مثال اگر می خواهید توان ۲ اعداد ۱ تا ۶ را در خروجی ترمینال ببینید، می توانید دستور awk را به صورت زیر اجرا کنید:
awk '{ for(i=1;i<=6;i++) print "square of", i, "is",i*i; }'
حلقه ی for اعداد ۱ تا ۶ را می شمارد. سپس دستور print هم آن را تحویل می گیرد و تحت قالب square of n is n * n در خروجی نشان می دهد.
square of 1 is 1
square of 2 is 4
square of 3 is 9
square of 4 is 16
square of 5 is 25
square of 6 is 36
استفاده از متغیرها در داخل دستور awk
اگر در داخل اسکریپت دستور awk نیاز به متغیری دارید که باید برای جلو بردن عملیات از آن استفاده کنید، می توانید با آپشن v آن را تعریف کنید:
مثلاً اگر می خواهید برای تعداد فروش انجام شده توسط فروشنده های مختلف که اطلاعات آنها در فایل ذخیره شده است، یک معیار سنجش (مثلاً ۱۵۰) در نظر بگیرید و وضعیت فروشنده ها را بررسی کنید، می توانید دستور awk را به صورت زیر اجرا کنید:
awk -v v=150 '
{
if ($2 > v) {
print $1 " فروشش خوب است: " $2
} else {
print $1 " فروشش نیاز به بهبود دارد: " $2
}
}' sales.txt
معیار سنجش یعنی همان ۱۵۰ توسط v تعریف شده است که در داخل اسکریپت هم برای مقایسه عملکرد فروشنده ها از آن استفاده شده است.
خواندن اسکریپت از یک فایل
اگر می خواهید سورس کد موردنظر را از یک فایل آماده (با پسوند awk) بخوانید و اجرا کنید، می توانید از آپشن f کمک بگیرید.
فرض کنید فایل script.awk زیر حاوی اسکریپت میانگین گرفتن از ستون اول فایل file.txt است:
{sum+=$1}
END {print "Average =", sum/NR}
حالا می توانید این فایل را با دستور زیر اجرا کنید:
awk -f script.awk file.txt
شما می توانید متناسب با نیاز خود، اسکریپت های پیچیده تری را در فایل awk بنویسید و سپس به راحتی با دستور awk اجرا کنید.
پردازش فایل csv با awk
برای اینکه طرز کار کردن با متغیرهای seperator دستور awk در لینوکس را یاد بگیرید، سعی می کنیم با مثال هایی از دنیای واقعی جلو برویم.
فرض کنید که یک فایل csv دارید که محتوای آن به شکل زیر است:
Name,Age,Score
Ali,20,75
Sara,30,85
Reza,25,60
Maryam,40,90
همانطور که می بینید فیلدهای این فایل با , جدا شده اند، پس شما باید FS را برابر , قرار دهید تا جداسازی فیلدها بر اساس این کاراکتر انجام شود و عملیات موردنظر شما با موفقیت انجام شوند.
اگر هم می خواهید خروجی را طوری ببینید که بین هر فیلد به جای , یک tab بگذارید، باید از آپشن OFS کمک بگیرید.
دستور زیر این دو کار را برای شما انجام می دهد:
awk 'BEGIN { FS=","; OFS=" \t" } { print $1, $2, $3 }' data.csv
Name Age Score
Ali 20 75
Sara 30 85
Reza 25 60
sahar 40 90
به جز فیلد یا همان ستون ها، شما با رکوردها یا سطرها هم مواجه هستید که RS و ORS هم برای کار کردن با آنها هستند.
به عنوان مثال اگر در فایل موردنظر فاصله بین هر سطر دو خط است (در حالت پیش فرض یک خط است)، می توانید RS را طوری تنظیم کنید که تفکیک ردیف ها را بر اساس دو خط انجام دهد:
awk 'BEGIN { FS=","; RS="\n\n" } { print $1, $2, $3 }' data.csv
یا اگر می خواهید فاصله بین خطوط خروجی را دو خط لحاظ کنید، می توانید ORS را در دستور لحاظ کنید:
awk 'BEGIN { FS=","; ORS="\n\n" } { print $1, $2, $3 }' data.csv
پس FS و RS برای جداسازی فیلدها و رکوردها جهت پردازش استفاده می شود و OFS و ORS جنبه ظاهری دارند و برای ساختاربندی خروجی به کار می روند.
ذخیره سازی خروجی دستور awk
برای اینکه خروجی دستور awk را در یک فایل ذخیره کنید، می توانید از عملگر ریداریکت کمک بگیرید:
awk '/linux/ {print $3 "\t" $4}' file.txt > output.txt
این دستور ستون سوم و چهارم خطوطی که دارای حرف linux هستند را در فایل output ثبت می کند و در مسیر فعلی ترمینال ذخیره می کند. برای بررسی این فایل می توانید از دستور زیر کمک بگیرید:
cat output.txt
ترکیب awk با دستورات دیگر
همانطور که تا الان متوجه شده اید، دستور awk بسیار کاربردی است و با اکثر دستورات لینوکس هم قابل ترکیب است که این ویژگی به افزایش کارایی آن کمک می کند.
بیایید با چند نمونه از آنها آشنا شویم:
ترکیب awk با grep برای فیلتر کردن خطوط خاص
فرض کنید می خواهید logfile را بررسی کنید و فقط ستون های اول، دوم و پنجم خطوطی را ببینید که حاوی ERROR هستند:
grep 'ERROR' logfile.log | awk '{print $1, $2, $5}'
دستور grep خطوط حاوی ERROR را استخراج می کند و سپس به عنوان ورودی به دستور awk پایپ می کند. سپس دستور awk ستون اول، دوم و پنجم آن را در خروجی نمایش می دهد.
که البته با همان pattern هم می توانستید به این خروجی برسید:
awk '/ERROR/{print $1, $2, $5}' logfile.log
ترکیب awk با sed برای جایگزینی رشته ها
یکی از اصلی ترین کاربردهای دستور sed، جایگزین کردن یک عبارت با عبارت دیگر است. حالا بیایید قدرت دستور sed و awk را با هم یکی کنیم:
cat file.txt | sed 's/ /-/g' | awk '{OFS=_}{print$2}'
دستور cat فایل file.txt را باز می کند، دستور sed تمام فضاهای خالی را با ـ جایگزین می کند و دستور awk هم دوم را پرینت می کند.
ترکیب awk با sort برای مرتب سازی داده ها
شما می توانید ستون های موردنظر را با awk انتخاب کنید و سپس آنها را بر اساس حروف الفبا مرتب کنید:
awk '{print $2, $1}' file.txt | sort
ترکیب awk با head یا tail برای انتخاب خطوط خاص
اگر ستون ها را انتخاب کرده اید ولی می خواهید مطابق نیاز خود فقط چند ردیف را بررسی کنید، می توانید از دستور head یا tail کمک بگیرید.
awk '{print $1, $3}' file.txt | head -n 10
مثلاً این دستور فقط ۱۰ خط اول را نشان می دهد.
اگر با طرز کار head و tail آشنا شوید، استفاده از چنین دستوراتی برایتان راحت تر خواهد شد.
سخن آخر
دستور awk یک دستور بسیار پرکاربرد برای پردازش فایل های متنی است و با اینکه سعی کردیم به کاربردهای اصلی آن اشاره کنیم تا درک کاربرد و نحوه استفاده از آن برایتان راحت تر باشد ولی سعی کنید با تمرین های بیشتر، به قدرت واقعی این ابزار پی ببرید.