پس از جستجو و تبدیل متن، گام بعدی استخراج و پردازش دادههای ساختاریافته است. ابزارهای cut و awk دو ابزار کلیدی برای این کار هستند. cut یک ابزار ساده برای برش دادن و استخراج ستونها یا فیلدهاست، در حالی که awk یک زبان برنامهنویسی کامل برای پردازش دادههای متنی ساختاریافته است و قدرت بسیار بیشتری دارد.
cut
دستور cut برای برش دادن (Cutting) خطوط متن و استخراج بخشهای خاصی از آنها استفاده میشود. این ابزار بسیار سریع و کارآمد برای استخراج فیلدها از فایلهای CSV، لاگها و دادههای جدولی است.
ساختار کلی:
cut [option] [file...]
گزینههای اصلی cut
| گزینه | توضیح | مثال |
|---|---|---|
-c | استخراج بر اساس کاراکتر (Character) | cut -c 1-5 (کاراکترهای ۱ تا ۵) |
-f | استخراج بر اساس فیلد (Field) | cut -f 1,3 (فیلدهای ۱ و ۳) |
-d | تعیین جداکنندهی فیلدها (Delimiter) (پیشفرض: Tab) | cut -d ',' -f 2 (CSV با جداکنندهی کاما) |
-s | حذف خطوطی که جداکننده ندارند | cut -s -f 1 data.txt |
--complement | استخراج همهی فیلدها به جز فیلدهای مشخصشده | cut --complement -f 2 |
۱. استخراج با -c (کاراکترها)
مثالها:
-
استخراج ۵ کاراکتر اول هر خط:
echo "Hello World" | cut -c 1-5 # خروجی: Hello
-
استخراج کاراکترهای ۳ تا ۷:
echo "Hello World" | cut -c 3-7 # خروجی: llo W
-
استخراج کاراکترهای ۱، ۳ و ۵:
echo "Hello World" | cut -c 1,3,5 # خروجی: Hlo
-
استخراج از کاراکتر ۵ تا انتهای خط:
echo "Hello World" | cut -c 5- # خروجی: o World
-
استخراج کاراکترهای ثابت از یک فایل (مثلاً تاریخ و زمان از لاگ):
cut -c 1-19 log.txt
اگر لاگها با فرمت
YYYY-MM-DD HH:MM:SSشروع شوند، فقط تاریخ و زمان استخراج میشود.
۲. استخراج با -f و -d (فیلدها)
مثالها:
-
استخراج فیلد اول از یک فایل CSV (با جداکنندهی کاما):
echo "Ali,30,Tehran" | cut -d ',' -f 1 # خروجی: Ali
-
استخراج فیلدهای ۱ و ۳ از فایل
/etc/passwd(جداکننده::):cut -d ':' -f 1,3 /etc/passwd # خروجی: root:0, user:1000, ...
-
استخراج فقط نام کاربری از
/etc/passwd:cut -d ':' -f 1 /etc/passwd
-
استخراج فیلد دوم تا آخر (با
-):echo "field1:field2:field3:field4" | cut -d ':' -f 2- # خروجی: field2:field3:field4
-
استخراج فیلد اول و سوم تا پنجم:
cut -d ',' -f 1,3-5 data.csv
-
استفاده از جداکنندههای چندکاراکتری (با
-dفقط یک کاراکتر پشتیبانی میشود، اما میتوان ازtrو سپسcutاستفاده کرد):echo "field1||field2||field3" | tr -s '|' | cut -d '|' -f 2 # خروجی: field2
-
نمایش همهی فیلدها به جز فیلد دوم (با
--complement):echo "field1:field2:field3" | cut -d ':' --complement -f 2 # خروجی: field1:field3
۳. مثالهای پیشرفتهی cut
-
استخراج آدرسهای IP از خروجی
ifconfig:ifconfig | grep "inet " | cut -d ' ' -f 10
-
استخراج کدهای وضعیت HTTP از لاگهای Nginx (فرض: فرمت لاگ استاندارد):
tail -n 100 /var/log/nginx/access.log | cut -d ' ' -f 9
(فیلد نهم معمولاً کد وضعیت است)
-
استخراج اندازهی فایلها از خروجی
ls -l:ls -l | cut -d ' ' -f 5
(فیلد پنجم معمولاً اندازه است)
awk
دستور awk یک زبان برنامهنویسی کامل و قدرتمند برای پردازش متنهای ساختاریافته است. awk ورودی را خط به خط پردازش میکند، هر خط را بر اساس جداکنندهای به فیلدهایی تقسیم میکند و سپس میتوانید عملیاتهای مختلفی (محاسبات، شرطها، حلقهها، فرمتبندی) روی آن فیلدها انجام دهید.
ساختار کلی:
awk [options] 'pattern { action }' [file...]
-
pattern: شرطی که مشخص میکند کدام خطوط پردازش شوند (اختیاری). -
action: دستوراتی که روی خطوط مطابق باpatternاجرا میشوند. -
اگر
patternوجود نداشته باشد، همهی خطوط پردازش میشوند. -
اگر
actionوجود نداشته باشد، بهطور پیشفرض کل خط ($0) چاپ میشود.
ساختار ساده:
awk '{ print $1 }' file.txt
این دستور فیلد اول هر خط را چاپ میکند.
فیلدها در awk
-
$0: کل خط (همهی فیلدها) -
$1: فیلد اول -
$2: فیلد دوم -
$NF: آخرین فیلد (NF = Number of Fields) -
$(NF-1): یک فیلد قبل از آخرین
مثالهای پایهی awk
-
چاپ فیلد اول و سوم از
/etc/passwd:awk -F ':' '{ print $1, $3 }' /etc/passwd
-F ':'جداکنندهی فیلدها را به:تغییر میدهد. خروجی:root 0,user 1000, ... -
چاپ همهی خطوط (معادل
cat):awk '{ print $0 }' file.txt
-
چاپ شمارهی خط و فیلد اول:
awk '{ print NR, $1 }' file.txt
NRشمارهی خط فعلی (Number of Records) است. -
چاپ تعداد فیلدهای هر خط:
awk '{ print NF }' file.txt
-
چاپ فیلد اول و آخرین فیلد:
awk '{ print $1, $NF }' file.txt
-
چاپ خطوطی که بیشتر از ۳ فیلد دارند:
awk 'NF > 3 { print $0 }' file.txt
۱. استفاده از الگوها (Patterns) در awk
الگوها (Patterns) میتوانند شامل عبارات منظم، مقایسهها و ترکیب آنها باشند.
انواع الگوها:
| الگو | توضیح | مثال |
|---|---|---|
/regex/ | خطوطی که با عبارت منظم مطابقت دارند. | awk '/error/ { print }' |
! /regex/ | خطوطی که با عبارت منظم مطابقت ندارند. | awk '!/^#/ { print }' |
$field ~ /regex/ | فیلد خاص با عبارت منظم مطابقت دارد. | awk '$2 ~ /^[0-9]+$/' |
$field !~ /regex/ | فیلد خاص با عبارت منظم مطابقت ندارد. | awk '$1 !~ /root/' |
$field > value | مقایسهی عددی. | awk '$3 > 1000' |
$field == "string" | مقایسهی رشتهای. | awk '$1 == "root"' |
BEGIN | قبل از خواندن اولین خط اجرا میشود. | awk 'BEGIN { print "Start" }' |
END | بعد از خواندن آخرین خط اجرا میشود. | awk 'END { print "End" }' |
مثالها:
-
چاپ خطوط حاوی
error:awk '/error/ { print $0 }' log.txt
-
چاپ خطوطی که با
#شروع نمیشوند (کامنتها را نادیده میگیرد):awk '!/^#/ { print $0 }' config.conf
-
چاپ خطوطی که فیلد دوم آنها
adminاست:awk '$2 == "admin" { print $0 }' users.txt
-
چاپ خطوطی که فیلد سوم آنها بزرگتر از ۱۰۰۰ است:
awk '$3 > 1000 { print $0 }' data.txt
-
چاپ خطوطی که فیلد اول با
Aشروع میشود:awk '$1 ~ /^A/ { print $0 }' names.txt
۲. متغیرهای داخلی awk
| متغیر | توضیح |
|---|---|
NR | شمارهی خط فعلی (Number of Records). |
NF | تعداد فیلدها در خط فعلی (Number of Fields). |
FS | جداکنندهی فیلدها (Field Separator) - قابل تنظیم با -F. |
OFS | جداکنندهی فیلدها در خروجی (Output Field Separator) - پیشفرض: فاصله. |
RS | جداکنندهی رکوردها (Record Separator) - پیشفرض: خط جدید (\n). |
ORS | جداکنندهی رکوردها در خروجی (Output Record Separator) - پیشفرض: خط جدید (\n). |
FILENAME | نام فایل ورودی فعلی. |
FNR | شمارهی خط در فایل فعلی (برای چند فایل). |
مثالها:
-
چاپ شمارهی خط و کل خط:
awk '{ print NR, $0 }' file.txt
-
چاپ تعداد فیلدها و کل خط:
awk '{ print NF, $0 }' file.txt
-
تغییر جداکنندهی خروجی به
,(کاما):awk 'BEGIN { OFS = "," } { print $1, $2, $3 }' data.txt
۳. توابع داخلی awk
awk توابع داخلی زیادی دارد. برخی از مهمترین آنها:
| تابع | توضیح | مثال |
|---|---|---|
length($0) | طول رشته را برمیگرداند. | awk '{ print length($0) }' |
tolower($1) | رشته را به حروف کوچک تبدیل میکند. | awk '{ print tolower($1) }' |
toupper($1) | رشته را به حروف بزرگ تبدیل میکند. | awk '{ print toupper($1) }' |
substr($0, start, len) | زیررشتهای از رشته را استخراج میکند. | awk '{ print substr($0, 1, 5) }' |
gsub(/old/, "new", $1) | جایگزینی همهی موارد یک الگو در یک فیلد. | awk '{ gsub(/foo/, "bar", $1); print }' |
sub(/old/, "new", $1) | جایگزینی اولین مورد یک الگو در یک فیلد. | awk '{ sub(/foo/, "bar", $1); print }' |
split($0, arr, ",") | رشته را به آرایهای از بخشها تقسیم میکند. | awk '{ split($0, arr, ","); print arr[2] }' |
int($1) | تبدیل به عدد صحیح. | awk '{ print int($1) }' |
sprintf(fmt, expr) | فرمتبندی رشته (مشابه printf در C). | awk '{ print sprintf("%.2f", $1) }' |
مثالها:
-
چاپ طول هر خط:
awk '{ print NR, length($0) }' file.txt
-
تبدیل فیلد اول به حروف کوچک:
awk '{ print tolower($1) }' names.txt
-
جایگزینی همهی
#با--در خطوط:awk '{ gsub(/#/, "--", $0); print }' file.txt
-
استخراج ۳ کاراکتر اول فیلد دوم:
awk '{ print substr($2, 1, 3) }' data.txt
۴. ساختارهای کنترلی در awk
awk از ساختارهای کنترلی مشابه زبان C پشتیبانی میکند:
-
if-else:awk '{ if ($3 > 1000) print "Large:", $0; else print "Small:", $0 }' data.txt
-
forloop:awk '{ for (i = 1; i <= NF; i++) print "Field", i, ":", $i }' file.txt
-
whileloop:awk '{ i = 1; while (i <= NF) { print $i; i++ } }' file.txt
-
array(آرایه):awk '{ arr[$1]++ } END { for (key in arr) print key, arr[key] }' file.txt
مثالها:
-
محاسبهی مجموع فیلد دوم و نمایش آن در END:
awk '{ sum += $2 } END { print "Total:", sum }' data.txt
-
محاسبهی میانگین فیلد سوم:
awk '{ sum += $3; count++ } END { print "Average:", sum / count }' data.txt
-
شمارش تکرار کلمات (Word Count با awk):
awk '{ for (i = 1; i <= NF; i++) count[$i]++ } END { for (word in count) print word, count[word] }' text.txt
۵. فرمتبندی خروجی با printf
برای فرمتبندی دقیق خروجی، از printf استفاده کنید (مشابه زبان C):
awk '{ printf "%-10s %5d %8.2f\n", $1, $2, $3 }' data.txt
مشخصههای printf:
| مشخصه | توضیح |
|---|---|
%s | رشته |
%d | عدد صحیح |
%f | عدد اعشاری |
%.2f | عدد اعشاری با ۲ رقم اعشار |
%10s | رشته با عرض ۱۰ کاراکتر (راستچین) |
%-10s | رشته با عرض ۱۰ کاراکتر (چپچین) |
مثال:
awk '{ printf "Name: %-15s Age: %3d City: %s\n", $1, $2, $3 }' data.txt
مقایسهی cut و awk
| ویژگی | cut | awk |
|---|---|---|
| پیچیدگی | ساده و سریع | پیچیده و قدرتمند |
| پشتیبانی از Regex | خیر (فقط کاراکترها و فیلدها) | بله (کامل) |
| محاسبات | خیر | بله (جمع، میانگین، ...) |
| شرطها و حلقهها | خیر | بله (if, for, while) |
| آرایهها | خیر | بله |
| قالببندی خروجی | محدود | پیشرفته (printf) |
| تغییر جداکننده | بله (-d) | بله (-F یا FS) |
| پردازش فیلدها | فقط استخراج | استخراج + محاسبه + تغییر |
| کاربرد اصلی | استخراج سریع فیلدها | پردازش دادههای پیچیده |
مثالهای ترکیبی و پیشرفته
-
پیدا کردن ۵ دستور پرکاربرد از تاریخچه:
history | awk '{ count[$2]++ } END { for (cmd in count) print count[cmd], cmd }' | sort -rn | head -5
-
محاسبهی مجموع اندازهی فایلها در دایرکتوری:
ls -l | awk '{ sum += $5 } END { print "Total size:", sum, "bytes" }'
-
استخراج آدرسهای IP از یک فایل لاگ:
awk '{ match($0, /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/); if (RSTART) print substr($0, RSTART, RLENGTH) }' log.txt
-
تبدیل فایل CSV به فرمت خاص:
awk -F ',' '{ printf "ID: %s, Name: %s, Age: %d\n", $1, $2, $3 }' data.csv
-
استخراج خطاهای یک لاگ به همراه تاریخ و زمان:
awk '/ERROR/ { print $1, $2, $3, "ERROR occurred" }' log.txt
(اگر تاریخ و زمان در فیلدهای اول تا سوم باشند)
-
گروهبندی و شمارش بر اساس یک ستون (مشابه GROUP BY در SQL):
awk -F ',' '{ count[$3]++ } END { for (city in count) print city, count[city] }' users.csv
تعداد کاربران در هر شهر را محاسبه میکند.
-
فیلتر کردن خطوطی که طول آنها بیشتر از ۵۰ کاراکتر است:
awk 'length($0) > 50' file.txt
-
پیدا کردن بزرگترین عدد در یک ستون:
awk '{ if ($1 > max) max = $1 } END { print "Max:", max }' numbers.txt
-
تغییر جداکنندهی یک فایل CSV از کاما به تب:
awk 'BEGIN { FS = ","; OFS = "\t" } { $1 = $1; print }' data.csv > data.tsv
$1 = $1باعث میشود کهawkخط را باOFSجدید بازسازی کند. -
استخراج فیلدهای ۱ و ۲ و ترکیب آنها:
awk '{ print $1 "-" $2 }' data.txt
خلاصه و نکات کلیدی
-
cutبرای استخراج سریع فیلدها یا کاراکترها از دادههای ساده و ساختاریافته عالی است. زمانی که فقط نیاز به برش و نمایش بخشی از خط دارید، ازcutاستفاده کنید. -
awkیک زبان برنامهنویسی کامل برای پردازش دادههای متنی است. زمانی که نیاز به محاسبات، شرطها، حلقهها، آرایهها و فرمتبندی پیچیده دارید، ازawkاستفاده کنید. -
ترکیب
grep،sed،cutوawkقدرتی باورنکردنی برای پردازش متن در خط فرمان ایجاد میکند. یادگیری و تسلط بر این ابزارها، یکی از مهمترین مهارتها برای هر کاربر و مدیر لینوکس است.
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: منبع مستندات