awk تک خطیهای
آک چیست؟
Awk یک ابزار پردازش متنی چندمنظوره است که برای پردازش و تحلیل
متنها در سیستمهای لینوکس و سیستمهای مشابه یونیکس به کار
میرود. این ابزار به شما امکان میدهد تا متنها را با استفاده از
الگوها و فیلترهای مختلف جستجو و تغییر دهید. به طور خاص، awk برای پردازش و
استخراج دادههای جدولی یا فرمتدار بسیار مفید است. این ابزار دارای یک
زبان برنامهنویسی ساده برای تعریف الگوها و عملیات مورد نیاز است. به عبارت
دیگر، awk یک ابزار قدرتمند برای انجام وظایف پردازش متنی در خط فرمان لینوکس است.
جهت شروع کار، ابتدا یک فایل متنی برای انجام دستورها روی آن نیاز
داریم. فایل مورد نظر باید دارای متن لاتین و با فرمت txt, asccidoc, md باشد. اگر
چنین فایلی در سیستم خود موجود دارید آن را کپی کرده و در پوشهای مخصوص این
درس قرار دهید، اگر نه با دستور زیر میتوانید یک متن Loremipsum برای خود
تولید کنید
curl https://www.lipsum.com/feed/json | jq -r '.feed.lipsum' > dummy.txt
میتوانید جهت راحتی بیشتر و هماهنگی با این درس فایل تمرین را از آدرس زیر دانلود کنید.
متن حاصل از دستور را چند بار زیر خودش کپی کنید تا حجم بیشتری متن برای کار کردن داشته باشیم.
استفاده از آک به چه صورت است؟
آک به سه شکل قابل استفاده است.نوع اول: اجرای دستورات آک از یک فایل
awk -f myscript.awk inputfile.txt
نوع دوم: پایپ کردن خروجی دستور دیگری به آک
cat /etc/ssh/sshd_config | awk '/Port/'
نوع سوم: اجرای دستور آک به صورت مستقیم روی فایل مورد نظر
awk '/Port/' /etc/ssh/sshd_config
در این جزوه که در واقع برگ تقلبی برای آک و کاربردهای بیشمار آن است، ما بر روش سوم تمرکز خواهیم کرد.
آک بصورت کلی روی ستونهای متنی کار میکند، این ستونها فیلد (field) نامیده میشوند.
کلمات، رجکس و ترتیب کاراکترها در این جزوه الگو (pattern) نامیده میشوند.
اضافه کردن یک خط فاصله بین هر بند:
awk '1;{print ""}' dummy.txt
awk 'BEGIN{ORS="\n\n"};1' dummy.txt
اضافه کردن سه خط فاصله بین هر بند:
awk '1;{print ""}' dummy.txt
اضافه کردن شمارهی خطوط به متن و شمارش ناپیوستهی خطوط تمام فایلها:
یعنی چنانچه بعد از dummy.txt فایل دیگری هم به آک بدهید، هنگامی که شمارش به فایل دوم برسد دوباره از یک شروع به شمردن میکند.
awk '{print FNR "\t" $0}' dummy.txt*
اضافه کردن شمارهی خطوط به متن و شمارش پیوستهی خطوط تمام فایلها:
awk '{print FNR "\t" $0}' dummy.txt*
اضافه کردن شمارهی خطوط و مارجین از سمت چپ به متن :
awk '{printf("%5d : %s\n", NR,$0)}' dummy.txt
اضافه کردن شمارهی خطوط به شرط خالی نبودن خطوط :
awk 'NF{$0=++a " :" $0};{print}' dummy.txt
awk '{print (NF? ++a " :" :"") $0}' dummy.txt
شمارش خطوط یک فایل مانند wc -l:
awk 'END{print NR}' dummy.txt
انجام عمیات ریاضی جمع بر روی تمام فیلدهای عددی یک فایل بصورت جداگانه:
مناسب فایلهای آماری
برای مثال فایلی با محتوای زیر:
| Days | SSH Users | Offline | Idle Users | FTP Users | Sat | 231 | 53 | 12 | 435 | Sun | 874 | 13 | 849 | 56 | Mon | 837 | 339 | 4434 | 90
awk '{s=0; for (i=1; i<=NF; i++) s=s+$i; print s}' stats.txt
انجام عمیات ریاضی جمع بر روی تمام فیلدهای عددی یک فایل و اعلام نتیجهی کلی:
awk '{for (i=1; i<=NF; i++) s=s+$i}; END{print s}' stats.txt
نمایش قدر مطلق هر فیلد عددی (Absolute Value):
awk '{for (i=1; i<=NF; i++) if ($i < 0) $i = -$i; print }'
awk '{for (i=1; i<=NF; i++) $i = ($i < 0) ? -$i : $i; print }'
نمایش تعداد کلی فیلدها - شمارش تغداد واژگان یک فایل:
awk '{ total = total + NF }; END {print total}' dummy.txt
نمایش تعداد تمامی خطوطی که شامل یک الگوی خاص هستند:
در اینجا از الگوی Lorem استفاده شده
مناسب شمارش تعداد سایتیشن در متن علمی یا تعداد لاگین یک کاربر در یک لاگ فایل
awk '/Lorem/{n++}; END {print n+0}' dummy.txt
نمایش تعداد فیلد در هر خط:
awk '{ print NF ":" $0 } ' dummy.txt
نمایش آخرین فیلد هر خط:
awk '{ print $NF }' dummy.txt
نمایش آخرین فیلد آخرین خط:
awk '{ field = $NF }; END{ print field }' dummy.txt
نمایش اولین فیلد هر خط:
awk '{ print $1 }' dummy.txt
نمایش چهارمین فیلد هر خط:
awk '{ print $4 }' dummy.txt
نمایش تمام خطوطی که بیش از چهار فیلد دارند:
awk 'NF > 4' dummy.txt
حذف فضاهای سفیدی ابتدایی (فاصلهها، تبها):
awk '{sub(/^[ \t]+/, ""); print}' dummy.txt
حذف فضاهای سفید انتهایی (فاصلهها، تبها) از انتهای هر خط:
awk '{sub(/[ \t]+$/, "");print}'
حذف هم فضای سفید ابتدایی و انتهایی از هر خط:
awk '{gsub(/^[ \t]+|[ \t]+$/,"");print}' dummy.txt
این دستور فاصلهی اضافی بین فیلدها را هم حذف میکند
awk '{$1=$1;print}' dummy.txt
درج 5 فضای خالی در ابتدای هر خط (ساخت ترتیب صفحه):
awk '{sub(/^/, " ");print}' dummy.txt
راستچین کردن تمام متن با عرض ۷۹ کاراکتر:
awk '{printf "%79s\n", $0}' dummy.txt*
وسطچین کردن تمام متن با عرض ۷۹ کاراکتر:
awk '{l=length();s=int((79-l)/2); printf "%"(s+l)"s\n",$0}' dummy.txt*
یافتن و جایگزینی الگوی اول با دوم:
awk '{sub(/Lorem/,"foo");print}' dummy.txt
برای بهتر دیدن خروجی این دستور میتوانید از grep استفاده کنید
awk '{sub(/Lorem/,"foo");print}' dummy.txt | grep --color=always foo
یافتن و جایگزینی، تنها در خطوطی که شامل یک الگوی خاص هستند:
در این دستور خطوطی که شامل الگوی Lorem هستند هدفگیری میشوند و در آن خطوط، الگوی ipsum با foo جایگزین خواهند شد.
awk '/Lorem/{gsub(/ipsum/, "foo")};{print}' dummy.txt
یافتن و جایگزینی در تمام خطوطی که شامل یک الگوی خاص نیستند (عکس دستور قبل):
awk '!/Lorem/{gsub(/sit/, "foo")};{print}' dummy.txt
جایگزینی گروهی واژگان با الگویی خاص:
awk '{gsub(/Lorem|ipsum|dolor/, "foo"); print}' dummy.txt
برعکس کردن ترتیب خطوط (مشابه tac):
awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' dummy.txt*
اگر یک خط با یک علامت \ پایان مییابد، خط بعدی را به آن اضافه کن:
awk '/\\$/ {sub(/\\$/,""); getline t; print $0 t; next}; 1' dummy.txt*
نمایش و مرتب سازی نامهای ورودی تمام کاربران:
awk -F ":" '{ print $1 | "sort" }' /etc/passwd
نمایش دو فیلد اول، به ترتیب معکوس، از هر خط:
awk '{print $2, $1}' dummy.txt
تعویض دو فیلد اول از هر خط:
awk '{temp = $1; $1 = $2; $2 = temp}' dummy.txt
نمایش همهی خطوط و حذف دومین فیلد آن خط:
awk '{ $2 = ""; print }' dummy.txt
نمایش همهي خطوط با ترتیب معکوس فیلدها:
awk '{for (i=NF; i>0; i--) printf("%s ",i);printf ("\n")}' dummy.txt
حذف خطوط تکراری و متوالی (شبیهسازی uniq):
awk 'a !~ $0; {a=$0}'
حذف خطوط تکراری و غیر متوالی :
awk '! a[$0]++'
awk '!($0 in a) {a[$0];print}'
نمایش ۱۰خط اول از فایل (شبیهسازی عملکرد head):
awk 'NR < 11'
نمایش اولین خط از فایل (شبیهسازی head -1):
awk 'NR>1{exit};1'
نمایش دو خط آخر یک فایل (شبیهسازی tail -2):
awk '{y=x "\n" $0; x=$0};END{print y}' dummy.txt
نمایش آخرین خط یک فایل (شبیهازی "tail -1):
awk 'END{print}' dummy.txt
نمایش تنها خطوطی که با الگو تطابق دارند (شبیهسازی grep):
awk '/Lorem/' dummy.txt
نمایش تنها خطوطی که با الگو تطابق ندارند (شبیهسازی grep -v):
awk '!/Lorem/' dummy.txt
نمایش خط قبل از یک الگو، اما خط حاوی الگو را نمایش نمیدهد:
awk '/Lorem/{print x};{x=$0}' dummy.txt
awk '/Lorem/{print (x=="" ? "تطابق در خط 1" : x)};{x=$0}' dummy.txt
نمایش خط پس از یک الگو، اما خط حاوی الگو را نمایش نمیدهد:
awk '/Lorem/{getline;print}' dummy.txt
گرفتن AAA و BBB و CCC (به هر ترتیب):
awk '/AAA/; /BBB/; /CCC/' dummy.txt
گرفتن AAA و BBB و CCC (به همان ترتیب):
awk '/AAA.*BBB.*CCC/' dummy.txt
نمایش تنها خطوطی با طول ۶۵ کاراکتر یا بیشتر:
awk 'length > 64' dummy.txt
نمایش تنها خطوطی با طول کمتر از ۶۵ کاراکتر:
awk 'length < 64' dummy.txt
نمایش بخشی از فایل از الگو تا انتهای فایل:
awk '/Lorem/,0' dummy.txt
awk '/Lorem/,EOF' dummy.txt
نمایش بخشی از فایل بر اساس شمارههای خط (خطوط ۸-۱۲):
awk 'NR==8,NR==12' dummy.txt
نمایش شماره خط ۵۲:
awk 'NR==52' dummy.txt
awk 'NR==52 {print;exit}' dummy.txt
در فایلهای بزرگ بهتر عمل میکند
نمایش بخشی از فایل بین دو الگو :
awk '/Iowa/,/Montana/' dummy.txt
حساس به حروف کوچک و بزرگ است
پاک کردن تمامی خطوط خالی از فایل(مشابه grep '.'):
awk NF dummy.txt
awk '/./' dummy.txt
- Sources:
- awk One-Liners By Eric Pement
- sed & awk, 2nd Edition, by Dale Dougherty and Arnold Robbins O'Reilly, 1997
- UNIX Text Processing, by Dale Dougherty and Tim O'Reilly Hayden Books, 1987
- Effective awk Programming, 3rd Edition. by Arnold Robbins O'Reilly, 2001