پس از جستجو و تبدیل متن، گام بعدی استخراج و پردازش دادههای ساختاریافته است. ابزارهای cut و awk دو ابزار کلیدی برای این کار هستند. cut یک ابزار ساده برای برش دادن و استخراج ستونها یا فیلدهاست، در حالی که awk یک زبان برنامهنویسی کامل برای پردازش دادههای متنی ساختاریافته است و قدرت بسیار بیشتری دارد.
دستور cut برای برش دادن (Cutting) خطوط متن و استخراج بخشهای خاصی از آنها استفاده میشود. این ابزار بسیار سریع و کارآمد برای استخراج فیلدها از فایلهای CSV، لاگها و دادههای جدولی است.
ساختار کلی:
cut [option] [file...]
| گزینه | توضیح | مثال |
|---|---|---|
-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
استخراج آدرسهای 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 [options] 'pattern { action }' [file...]
pattern: شرطی که مشخص میکند کدام خطوط پردازش شوند (اختیاری).
action: دستوراتی که روی خطوط مطابق با pattern اجرا میشوند.
اگر pattern وجود نداشته باشد، همهی خطوط پردازش میشوند.
اگر action وجود نداشته باشد، بهطور پیشفرض کل خط ($0) چاپ میشود.
ساختار ساده:
awk '{ print $1 }' file.txt
این دستور فیلد اول هر خط را چاپ میکند.
$0: کل خط (همهی فیلدها)
$1: فیلد اول
$2: فیلد دوم
$NF: آخرین فیلد (NF = Number of Fields)
$(NF-1): یک فیلد قبل از آخرین
چاپ فیلد اول و سوم از /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) میتوانند شامل عبارات منظم، مقایسهها و ترکیب آنها باشند.
انواع الگوها:
| الگو | توضیح | مثال |
|---|---|---|
/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
| متغیر | توضیح |
|---|---|
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 توابع داخلی زیادی دارد. برخی از مهمترین آنها:
| تابع | توضیح | مثال |
|---|---|---|
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 از ساختارهای کنترلی مشابه زبان C پشتیبانی میکند:
if-else:
awk '{ if ($3 > 1000) print "Large:", $0; else print "Small:", $0 }' data.txt
for loop:
awk '{ for (i = 1; i <= NF; i++) print "Field", i, ":", $i }' file.txt
while loop:
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 قدرتی باورنکردنی برای پردازش متن در خط فرمان ایجاد میکند. یادگیری و تسلط بر این ابزارها، یکی از مهمترین مهارتها برای هر کاربر و مدیر لینوکس است.
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: منبع مستندات