فصل ۲۱ – قالببندی خروجی
زمانی که اسکریپتها و فرمانهای خط فرمان داده تولید میکنند، لازم است خروجی را به شکلی قابل خواندن ارائه دهیم.
در این فصل با ابزارهایی آشنا میشویم که به ما کمک میکنند دادههای خام را به جدولها، گزارشها و قالبهای دیدنی تبدیل کنیم.
موضوعات اصلی شامل موارد زیر است:
- ایجاد جدولهای ساده با
columnوprintf. - استفاده از
printfدر شل و در برنامههای دیگر. - ابزارهای قالببندی مانند
expand،fmtوpr. - تبدیل دادهها با
awkوsedبرای تولید خروجی ساختیافته.
ستونبندی با column
دستور column ورودی را به ستونهایی با عرض برابر تبدیل میکند.
برای مثال خروجی /etc/passwd را میتوانیم به شکل دو ستونی نمایش دهیم:
cut -d: -f1,7 /etc/passwd | column -t -s:
گزینهٔ -t ستونها را مرتب میکند و -s جداکنندهٔ دلخواه را مشخص میسازد.
اگر ورودی تعداد ستونهای زیادی داشته باشد، column بهطور خودکار عرض ترمینال را در نظر میگیرد.
printf در خط فرمان
فرمان printf مشابه تابع همنامش در زبان C عمل میکند.
ساختار کلی:
printf "قالب" مقادیر...
در bash میتوانیم به شکل زیر استفاده کنیم:
printf "%-20s %10d\n" "Product" 42
نمادهای قالب متداول:
%sرشته.%dیا%iعدد صحیح.%fعدد اعشاری.%xعدد در مبنای شانزده.%%یک علامت درصد واقعی.
پرچمهایی مانند - (چپچین)، 0 (پر کردن با صفر) و تعیین عرض میدان به کنترل بیشتر کمک میکنند.
📘 جدول ۲۱-۱: توالیهای escape متداول در printf
| توالی | توضیح |
|---|---|
\n |
شروع خط جدید |
\t |
تب افقی |
\r |
بازگشت به ابتدای خط |
\a |
آژیر (bell) |
\\ |
چاپ یک backslash |
استفادهٔ درست از این توالیها برای ساخت خروجی چندخطی یا جدولهای پیچیده ضروری است.
قالبهای پیشرفته
printf میتواند چندین مقدار را پشت سر هم چاپ کند:
while read name price; do
printf "%-25s %8.2f\n" "$name" "$price"
done < products.txt
در مثال بالا، نام و قیمت کالاها در قالب یک جدول با دو ستون نمایش داده میشوند.
میتوانیم خروجی را به فایل هدایت کنیم یا همراه با ابزارهای دیگر زنجیر کنیم.
از printf در برنامههایی مانند awk نیز استفاده میشود:
awk -F',' '{ printf "%-20s %6d\n", $1, $3 }' sales.csv
این دستور نام محصول (ستون اول) و تعداد فروش (ستون سوم) را با قالببندی مناسب چاپ میکند.
استفاده از sed برای قالببندی ساده
sed فقط برای ویرایش خطی نیست؛ میتواند قالببندی اولیه نیز انجام دهد.
برای مثال تبدیل فهرست کلید=مقدار به جدول دونقطهای:
sed 's/=/: /' config.list | column -t -s:
یا افزودن کامنت به خطوط انتخابی:
sed '/^#/!s/^/# /' notes.txt
استفاده از awk برای گزارشگیری
awk زبان کوچکی برای پردازش متن است.
میتوانیم ستونها را انتخاب کنیم، محاسبه انجام دهیم و گزارش بسازیم.
awk -F',' '
BEGIN {
printf "%-20s %10s %10s\n", "Product", "Units", "Revenue";
printf "%s\n", "-------------------------------------------";
}
{
revenue = $3 * $4;
total_units += $3;
total_revenue += revenue;
printf "%-20s %10d %10.2f\n", $1, $3, revenue;
}
END {
printf "%s\n", "-------------------------------------------";
printf "%-20s %10d %10.2f\n", "TOTAL", total_units, total_revenue;
}
' sales.csv
در بخش BEGIN سرستونها چاپ میشوند، در بدنهٔ اصلی برای هر رکورد خروجی تولید میگردد و در END جمع کل گزارش داده میشود.
تنظیم عرض متن و صفحهبندی
ابزار fmt پاراگرافها را به طول مشخص میشکند و fold خطوط را بدون توجه به کلمه قطع میکند.
برای چاپ گزارش روی کاغذ، pr سربرگ و شمارهٔ صفحه اضافه میکند:
pr -h "Sales Report" -l 60 report.txt
گزینهٔ -h عنوان صفحه، -l تعداد خطوط هر صفحه و -d برای حالت «double-space» به کار میرود.
همتراز کردن دادهها با Bash
در اسکریپتها گاهی لازم است جدولهایی با عرضهای ثابت ایجاد کنیم.
میتوانیم از محاسبات طول رشته استفاده کنیم:
pad() {
local text="$1"
local width="$2"
printf "%-${width}s" "$text"
}
printf "| %s | %s |\n" "$(pad "Name" 15)" "$(pad "Phone" 12)"
printf "|-%s-|-%s-|\n" "$(printf '%.0s-' {1..15})" "$(printf '%.0s-' {1..12})"
این الگو زمینهٔ مناسبی برای ساخت جدولهای سفارشی در اسکریپتها فراهم میکند.
تولید خروجی برای فرمتهای دیگر
گاهی لازم است خروجی را به فرمتهایی نظیر CSV یا HTML تبدیل کنیم.
با ابزارهایی مانند printf, sed و awk میتوانیم این کار را انجام دهیم.
نمونهٔ CSV:
awk 'BEGIN { OFS="," } { print $1, $2, $3 }' data.txt
نمونهٔ HTML:
awk '
BEGIN {
print "<table>";
}
{
printf " <tr><td>%s</td><td>%s</td></tr>\n", $1, $2;
}
END {
print "</table>";
}
' table.txt
جمعبندی
قالببندی مناسب خروجی، خوانایی گزارشها و اسکریپتها را افزایش میدهد.
با ترکیب ابزارهای سنتی یونیکس میتوان خروجی را به هر شکل دلخواهی درآورد؛ مهم این است که قالب مورد نظر را دقیق مشخص کنیم و سپس با فیلترهای متن مناسب به آن برسیم.
در فصل بعدی خواهیم دید چگونه خروجیهای فرمتشده را روی کاغذ یا چاپگر ارسال کنیم.
تمرین
- فایلی شامل نام، قیمت و تعداد کالا تهیه کنید و با استفاده از
awkگزارشی شبیه مثال این فصل بسازید که ستون جمع کل را هم اضافه کند. - خروجی فرمان
df -hرا طوری باcolumnوprintfقالببندی کنید که تنها نام mount point و فضای خالی باقی بماند. - با بهرهگیری از
printfدر Bash، یک جدول سهستونی بسازید که سرفصلها را وسطچین و دادهها را راستچین نمایش دهد.
مطالعهٔ بیشتر
- مستند
info printfدر پروژهٔ GNU جزئیات همهٔ توصیفگرهای قالب را فهرست میکند. - برای ایدههای بیشتر دربارهٔ گزارشسازی با
awk، به کتاب «The AWK Programming Language» مراجعه کنید. - صفحهٔ راهنمای
man columnوman prمثالهای بیشتری دربارهٔ قالببندی خروجی ارائه میدهند.