در بخش 8 از سری آموزش های AWK، چند ویژگی قدرتمند از دستور awk در لینوکس را معرفی کردیم، که شامل متغیرها (variables)، عبارت های عددی (numeric expressions) و عملگرهای انتسابی (assignment operators) می شدند. تا جایی که پیش رفتیم، در این بخش می خواهیم ویژگی های بیشتری از awk را آموزش دهیم که شامل الگوهای خاص BEGIN و END میشود :
همانطور که ما برای گسترش و کشف روش های بیشتری برای ایجاد عملیات پیچیده با awk تلاش میکنیم، ثابت خواهد شد که این ابزار خاص تا چقدر مفید و مهم است.
برای شروع، به قسمت معرفی awk برمی گردیم. نحوه کلی نوشتن دستور awk اینگونه است :
و در دستور بالا، قالب نوشتاری awk به این شکل است :
زمانیکه ما الگو را در اسکریپت لحاظ میکنیم، به صورت نرمال این الگو یک عبارت خاص (regular expression) میباشد علاوه بر این شما میتوانید به این پترن به منزله الگوهای خاص BEGIN و END نگاه کنید. بنابراین ما همچنین میتوانیم یک دستور awk را به شکل زیر بنویسیم.
در event بالا که شما از الگوهای خاص BEGIN و END در دستور Awk استفاده کردید، هر کدام از آنها بصورت زیر تفسیر می شود:
الگوی BEGIN : یعنی awk در حقیقت action هایی که در قسمت BEGIN مشخص شده اند را قبل از اینکه هر خط ورودی دیگری را بخواند، اجرا خواهد کرد.
الگوی END : یعنی awk در حقیقت action هایی که در قسمت END مشخص شده اند را قبل از اینکه به کار خود خاتمه دهد، اجرا خواهد کرد.
روند اجرای اسکریپت دستور awk که شامل این الگوهای خاص میباشد، به صورت زیر است :
زمانیکه الگوی BEGIN در یک اسکریپت استفاده میشود تمامی اکشن ها برای BEGIN قبل از اینکه هر خط دیگری خوانده شود، اجرا میشوند.
سپس یک خط ورودی خوانده شده و به فیلد های متفاوتی تجزیه میشود.
سپس هر الگوی غیر ویژه ی (non-special) مشخص با خط ورودی برای هر گونه match شدن مقایسه میشوند و در صورت هر گونه match شدن اکشن ها برای آن الگو اجرا خواهند شد. این مرحله برای تمامی الگوهایی که شما مشخص کرده اید تکرار خواهد شد.
سپس، مرحله 2 و 3 برای تمام خطوط ورودی تکرار می شوند.
وقتی تمام خطوط ورودی خوانده شدند و دستورات انجام شد، در صورتی که از الگوی END استفاده کرده باشید، action های آن بخش نیز اجرا می شوند.
همیشه باید این روند از اجرا را هنگامی که از الگوهای خاص استفاده می کنید به یاد داشته باشید تا بهترین نتایج را از عملگرهای Awk ببینید.
برای اینکه طرز کار را کاملا متوجه شده باشید، بیایید این الگو را با استفاده از مثال بخش 8 در مورد فهرستی از دامنه ها که متعلق به linux-zone.org است و در فایلی به نام domains.txt قرار دارد توضیحح دهیم.
در این مثال، می خواهیم تعداد دفعاتی که دامنه ی linux-zone.org در فایل domains.txt لیست شده اند را بشماریم. برای اینکار یک shell script کوچک نوشتیم که به ما کمک میکند تا با استفاده از متغیر ها، عبارت های عددی و عملگرهای انتسابی این کار را انجام دهیم که اسکریپت ما محتوای زیر را دارد.
اکنون دو الگوی خاص BEGIN و END را در دستور awk و در اسکریپت بالا بصورت زیر به کار میبریم.
اسکریپت زیر را :
به صورت زیر تغییر می دهیم.
بعد از اعمال تغییرات در دستور awk، محتوای shell script کامل شبیه به مورد زیر میشود.
هنگامی که اسکریپت بالا را اجرا می کنیم، ابتدا مسیر فایل domains.txt را نمایش می دهد، سپس دستور Awk اجرا می شود که الگوی خاص BEGIN کمک می کند قبل از اینکه خطوط ورودی دیگری از فایل خوانده شوند، متن زیر نمایش داده شود :
سپس الگوی /^linux-zone.org/ با هر خط ورودی مقایسه می شود و اکشن { counter+=1 ; } برای هر خط ورودی اجرا میشود، که تعداد دفعاتی که linux-zone.org در فایل وجود دارد را شمارش می کند.
در نهایت، الگوی END، تعداد کل دفعاتی که دامین linux-zone.org در فایل وجود داشته را نمایش میدهد. (همانند بالا)
در مجموع، با ویژگی های بیشتری از Awk آشنا شدیم و با مفهوم الگوهای خاص BEGIN و END کار کردیم.
همانطور که قبلا هم اشاره کردیم،این ویژگی های Awk در ایجاد عملیات پیچیده ی فیلتر کردن متن به ما کمک خواهد کرد. ویژگی های بیشتری از Awk هست که در بخش 10 آموزش خواهیم داد و با مفهوم متغیرهای built-inn آشنا خواهیم شد، پس با ما همراه باشید.
همانطور که ما برای گسترش و کشف روش های بیشتری برای ایجاد عملیات پیچیده با awk تلاش میکنیم، ثابت خواهد شد که این ابزار خاص تا چقدر مفید و مهم است.
برای شروع، به قسمت معرفی awk برمی گردیم. نحوه کلی نوشتن دستور awk اینگونه است :
کد PHP:
# awk 'script' filenames
کد PHP:
/pattern/ { actions }
کد PHP:
awk '
BEGIN { actions }
/pattern/ { actions }
/pattern/ { actions }
……….
END { actions }
' filenames
الگوی BEGIN : یعنی awk در حقیقت action هایی که در قسمت BEGIN مشخص شده اند را قبل از اینکه هر خط ورودی دیگری را بخواند، اجرا خواهد کرد.
الگوی END : یعنی awk در حقیقت action هایی که در قسمت END مشخص شده اند را قبل از اینکه به کار خود خاتمه دهد، اجرا خواهد کرد.
روند اجرای اسکریپت دستور awk که شامل این الگوهای خاص میباشد، به صورت زیر است :
زمانیکه الگوی BEGIN در یک اسکریپت استفاده میشود تمامی اکشن ها برای BEGIN قبل از اینکه هر خط دیگری خوانده شود، اجرا میشوند.
سپس یک خط ورودی خوانده شده و به فیلد های متفاوتی تجزیه میشود.
سپس هر الگوی غیر ویژه ی (non-special) مشخص با خط ورودی برای هر گونه match شدن مقایسه میشوند و در صورت هر گونه match شدن اکشن ها برای آن الگو اجرا خواهند شد. این مرحله برای تمامی الگوهایی که شما مشخص کرده اید تکرار خواهد شد.
سپس، مرحله 2 و 3 برای تمام خطوط ورودی تکرار می شوند.
وقتی تمام خطوط ورودی خوانده شدند و دستورات انجام شد، در صورتی که از الگوی END استفاده کرده باشید، action های آن بخش نیز اجرا می شوند.
همیشه باید این روند از اجرا را هنگامی که از الگوهای خاص استفاده می کنید به یاد داشته باشید تا بهترین نتایج را از عملگرهای Awk ببینید.
برای اینکه طرز کار را کاملا متوجه شده باشید، بیایید این الگو را با استفاده از مثال بخش 8 در مورد فهرستی از دامنه ها که متعلق به linux-zone.org است و در فایلی به نام domains.txt قرار دارد توضیحح دهیم.
کد PHP:
news.linux-zone.org
linux-zone.org
digium.ir
windows.linux-zone.org
linux-zone.org
news.linux-zone.org
linux-zone.org
digium.ir
linux-zone.org
news.linux-zone.org
linux-zone.org
digium.ir
windows.linux-zone.org
linux-zone.org
کد PHP:
$ cat ~/domains.txt
در این مثال، می خواهیم تعداد دفعاتی که دامنه ی linux-zone.org در فایل domains.txt لیست شده اند را بشماریم. برای اینکار یک shell script کوچک نوشتیم که به ما کمک میکند تا با استفاده از متغیر ها، عبارت های عددی و عملگرهای انتسابی این کار را انجام دهیم که اسکریپت ما محتوای زیر را دارد.
کد PHP:
#!/bin/bash
for file in $@; do
if [ -f $file ] ; then
# اسم فایل را نمایش بده
echo "File is: $file"
# یک عدد صعودی را به ازای هر خط که شامل linux-zone.org باشد را نمایش بده.
awk '/^linux-zone.org/ { counter+=1 ; printf "%s\n", counter ; }' $file
else
# در صورتی که ورودی یک فایل نیست ارور نمایش بده
echo "$file is not a file, please specify a file." >&2 && exit 1
fi
done
# در صورت اجرای کامل، اسکریپت را با exit code 0 به اتمام برسان
exit 0
اکنون دو الگوی خاص BEGIN و END را در دستور awk و در اسکریپت بالا بصورت زیر به کار میبریم.
اسکریپت زیر را :
کد PHP:
awk '/^linux-zone.org/ { counter+=1 ; printf "%s\n", counter ; }' $file
کد PHP:
awk ' BEGIN { print "The number of times linux-zone.org appears in the file is:" ; }
/^linux-zone.org/ { counter+=1 ; }
END { printf "%s\n", counter ; }
' $file
کد PHP:
#!/bin/bash
for file in $@; do
if [ -f $file ] ; then
#اسم فایل را نمایش بده
echo "File is: $file"
# یک عدد صعودی را به ازای هر خط که شامل linux-zone.org باشد را نمایش بده.
awk ' BEGIN { print "The number of times linux-zone.org appears in the file is:" ; }
/^linux-zone.org/ { counter+=1 ; }
END { printf "%s\n", counter ; }
' $file
else
# ﺩﺭ صورتی که ورودی یک فایل نیست Error نمایش بده.
echo "$file is not a file, please specify a file." >&2 && exit 1
fi
done
# ﺩﺭ صورت اجرای کامل، اسکریپت را با exit code 0 به اتمام برسان.
exit 0
کد PHP:
parham@parham:~$ ./script.sh ~/domains.txt
File is: /home/parham/domains.txt
The number of times linux-zone.org appears in the file is:
6
parham@parham:~$
در نهایت، الگوی END، تعداد کل دفعاتی که دامین linux-zone.org در فایل وجود داشته را نمایش میدهد. (همانند بالا)
کد PHP:
$ ./script.sh ~/domains.txt
همانطور که قبلا هم اشاره کردیم،این ویژگی های Awk در ایجاد عملیات پیچیده ی فیلتر کردن متن به ما کمک خواهد کرد. ویژگی های بیشتری از Awk هست که در بخش 10 آموزش خواهیم داد و با مفهوم متغیرهای built-inn آشنا خواهیم شد، پس با ما همراه باشید.