توی این درس یاد میگیری قدرت اصلی لینوکس این است که دستورهای کوچک را مثل قطعههای لگو به هم وصل کنی. علامت | (pipe) خروجی یک دستور را به ورودی دستور بعدی میدهد. با چند دستور ساده، sort (مرتبسازی)، uniq -c (شمارش تکراریها)، cut (برش ستون)، tr (تبدیل کاراکتر)، wc (شمارش) و xargs (تبدیل خروجی به argument)، کارهای تحلیلی بزرگ انجام میدهی. تمرین اصلی: از یک فایل لاگ وبسرور، ۱۰ آدرس IP پرتکرار را پیدا میکنی.
مسئله: یک ابزار برای همهچیز؟ نه!
Section titled “مسئله: یک ابزار برای همهچیز؟ نه!”در بعضی سیستمها هر کار یک برنامهی بزرگ با دکمههای بیشمار دارد. یونیکس راه دیگری رفت: هر برنامه یک کار را خوب انجام بدهد و برنامهها بتوانند خروجیشان را به هم بدهند. نتیجه: بهجای ابزار «تحلیلگر لاگ»، چند دستور کوچک را به هم میچسبانی و هر سؤالی که به ذهنت برسد جواب میگیری، حتی سؤالی که سازندهی ابزارها فکرش را نکرده بود.
تشبیه: خط تولید کارخانه
Section titled “تشبیه: خط تولید کارخانه”کارخانهی خط تولید: هر ایستگاه یک کار ساده انجام میدهد (برش، شستوشو، بستهبندی) و محصول را به ایستگاه بعدی میدهد. هر ایستگاه فقط میداند «ورودیام چیست و خروجیام چه باید باشد». pipe نوار نقاله بین ایستگاههاست. و چون ایستگاهها همزمان کار میکنند، نتیجهی اول قبل از تمام شدن همهی دادهها هم آماده میشود.
مثالهای عملی
Section titled “مثالهای عملی”برای تمرین، یک لاگ وبسرور نمونه (۳۰۰۰ خط، با IP های مستندسازی) میسازیم. (از awk فقط برای ساختن داده استفاده میکنم؛ در درسهای بعد یادش میگیری.)
awk 'function rnd(n) { x = (x * 69069 + 1) % 4294967296; return int(x / 65536) % n }BEGIN { x = 42 split("203.0.113.5 203.0.113.5 203.0.113.5 203.0.113.5 203.0.113.5 198.51.100.7 198.51.100.7 198.51.100.7 192.0.2.44 192.0.2.44 203.0.113.9 198.51.100.23 192.0.2.8 203.0.113.77", ip, " ") split("200 200 200 200 200 200 301 404 404 500", st, " ") split("/index.html /about /api/users /api/orders /login /static/app.js /favicon.ico", pa, " ") for (i = 1; i <= 3000; i++) printf "%s - - [03/Oct/2026:12:%02d:%02d +0000] \"GET %s HTTP/1.1\" %s %d\n", ip[rnd(14) + 1], int(i / 60) % 60, i % 60, pa[rnd(7) + 1], st[rnd(10) + 1], 200 + rnd(5000)}' > access.logwc -l access.loghead -3 access.log3000 access.log203.0.113.5 - - [03/Oct/2026:12:00:01 +0000] "GET /static/app.js HTTP/1.1" 404 3077203.0.113.5 - - [03/Oct/2026:12:00:02 +0000] "GET /api/users HTTP/1.1" 500 3204192.0.2.44 - - [03/Oct/2026:12:00:03 +0000] "GET /favicon.ico HTTP/1.1" 200 2811هر خط: IP، زمان، درخواست، کد وضعیت (ستون ۹: ۲۰۰ موفق، ۴۰۴ پیدا نشد، ۵۰۰ خطای سرور) و حجم پاسخ. ستونها با فاصله جدا شدهاند.
مثال ۱: اولین pipe
Section titled “مثال ۱: اولین pipe”| خروجی دستور چپ را به ورودی دستور راست میدهد:
ls /etc | head -5echo "--- تعداد آیتمهای /etc:"ls /etc | wc -lecho "--- ۳ خط وسط (خطهای 5 تا 7):"head -n 7 access.log | tail -n 3X11adduser.confalternativesapparmor.dapt--- تعداد آیتمهای /etc:140--- ۳ خط وسط (خطهای 5 تا 7):198.51.100.23 - - [03/Oct/2026:12:00:05 +0000] "GET /index.html HTTP/1.1" 200 3611198.51.100.23 - - [03/Oct/2026:12:00:06 +0000] "GET /api/users HTTP/1.1" 404 4617198.51.100.7 - - [03/Oct/2026:12:00:07 +0000] "GET /static/app.js HTTP/1.1" 404 4871در ls /etc | head -5، ls خروجیاش (صدها اسم) را به head میدهد و head فقط پنج تا را نگه میدارد. دستور سوم دو برنامه را برای «برش از وسط» ترکیب کرد. هر pipeline میتواند هر چند حلقه داشته باشد.
مثال ۲: مرتبسازی، sort
Section titled “مثال ۲: مرتبسازی، sort”sort خطها را مرتب میکند. پیشفرض: الفبایی (نه عددی!):
printf '10\n9\n100\n2\n' | sortecho "--- sort -n (عددی):"printf '10\n9\n100\n2\n' | sort -necho "--- sort -rn (عددی، معکوس):"printf '10\n9\n100\n2\n' | sort -rnecho "--- sort -u (مرتب و حذف تکراری):"printf 'b\na\nb\nc\na\n' | sort -u1010029--- sort -n (عددی):2910100--- sort -rn (عددی، معکوس):1001092--- sort -u (مرتب و حذف تکراری):abcبدون -n، ۱۰۰ قبل از ۲ میآید (مقایسهی کاراکتر به کاراکتر: 1 < 2). flag های مهم: -n عددی، -r معکوس، -u یکتا، -h اعداد خوانا مثل 2K 1M (برای خروجی du -h)، -k N مرتبسازی بر اساس ستون N، -t X جداکنندهی ستون:
echo "--- مرتبسازی /etc/passwd بر اساس UID، بزرگترینها اول (ستون 3، جداکننده :):"sort -t: -k3 -nr /etc/passwd | head -3 | cut -d: -f1,3--- مرتبسازی /etc/passwd بر اساس UID، بزرگترینها اول (ستون 3، جداکننده :):nobody:65534ali:1001ubuntu:1000مثال ۳: شمارش تکراریها، uniq -c
Section titled “مثال ۳: شمارش تکراریها، uniq -c”uniq خطهای پشتسرهم یکسان را یکی میکند، پس ورودی باید مرتب باشد؛ -c تعداد را کنارش مینویسد:
echo "--- بدون sort (فقط تکرارهای پشتسرهم یکی میشوند):"printf 'a\nb\na\na\nb\n' | uniq -cecho "--- با sort اول:"printf 'a\nb\na\na\nb\n' | sort | uniq -cecho "--- فقط تکراریها (-d):"printf 'a\nb\na\nc\n' | sort | uniq -decho "--- فقط یکتاها (-u):"printf 'a\nb\na\nc\n' | sort | uniq -u--- بدون sort (فقط تکرارهای پشتسرهم یکی میشوند): 1 a 1 b 2 a 1 b--- با sort اول: 3 a 2 b--- فقط تکراریها (-d):a--- فقط یکتاها (-u):bcالگوی ثابت: sort | uniq -c برای «هر مقدار چند بار آمده». این یکی از رایجترین ترکیبهای لینوکس است.
چرا قبل از uniq معمولاً sort میزنیم؟
بدون sort، مثلاً a b a دو a جداگانه میماند.
مثال ۴: برش ستون، cut
Section titled “مثال ۴: برش ستون، cut”cut بخشی از هر خط را برش میدهد: -d جداکننده، -f شمارهی ستون (fields)، -c شمارهی کاراکتر:
echo "--- ستون ۱ (IP) از ۳ خط اول:"head -3 access.log | cut -d' ' -f1echo "--- ستونهای ۱ و ۹ (IP و وضعیت):"head -3 access.log | cut -d' ' -f1,9echo "--- ۱۰ کاراکتر اول:"head -2 access.log | cut -c1-10echo "--- نام کاربرها از /etc/passwd (جداکننده :):"cut -d: -f1 /etc/passwd | head -4--- ستون ۱ (IP) از ۳ خط اول:203.0.113.5203.0.113.5192.0.2.44--- ستونهای ۱ و ۹ (IP و وضعیت):203.0.113.5 404203.0.113.5 500192.0.2.44 200--- ۱۰ کاراکتر اول:203.0.113.203.0.113.--- نام کاربرها از /etc/passwd (جداکننده :):rootdaemonbinsysبرای فایلهایی که ستونهایشان با فاصلهی متغیر جدا شدهاند (مثل خروجی ps یا df) cut -d' ' درست کار نمیکند؛ آنجا از awk استفاده کن (درس بعد). دو حالت مفید دیگر: -f2- (از ستون ۲ تا آخر) و --complement.
مثال ۵: تبدیل کاراکتر، tr
Section titled “مثال ۵: تبدیل کاراکتر، tr”tr (translate) کاراکتر به کاراکتر تبدیل یا حذف میکند. فقط از stdin میخواند (فایل نمیگیرد):
echo "hello world" | tr 'a-z' 'A-Z'echo "--- حذف کاراکتر (-d):"echo "شماره: 0912-345-6789" | tr -d '-'echo "--- فشرده کردن تکرار (-s):"echo "a b c" | tr -s ' 'echo "--- تبدیل فاصله به خط جدید:"echo "one two three" | tr ' ' '\n'echo "--- حذف کاراکتر \\r فایل ویندوزی:"printf 'line1\r\nline2\r\n' | tr -d '\r' | od -c | head -2HELLO WORLD--- حذف کاراکتر (-d):شماره: 09123456789--- فشرده کردن تکرار (-s):a b c--- تبدیل فاصله به خط جدید:onetwothree--- حذف کاراکتر \r فایل ویندوزی:0000000 l i n e 1 \n l i n e 2 \n0000014کاربردهای رایج: حروف بزرگ/کوچک، حذف \r (فایلهایی که از ویندوز آمدهاند)، فشرده کردن فاصلههای اضافی، و شکستن کلمهها به خطهای جدا (برای شمارش کلمات).
مثال ۶: وضعیت کدهای HTTP
Section titled “مثال ۶: وضعیت کدهای HTTP”با همین ابزارها یک گزارش بساز: هر کد وضعیت چند بار آمده؟
cut -d' ' -f9 access.log | sort | uniq -c | sort -rn 1783 200 624 404 315 301 278 500سه حلقه: cut ستون وضعیت را برید، sort | uniq -c شمرد، و sort -rn از بیشترین به کمترین چید. ۲۰۰ بیشترین است (موفق)، بعد ۴۰۴ و … . یک گزارش «چند درصد خطا داریم؟» فقط یک خط دیگر لازم دارد:
total=$(wc -l < access.log)errors=$(cut -d' ' -f9 access.log | grep -c '^[45]')echo "خطا: $errors از $total درخواست"خطا: 902 از 3000 درخواست(grep را در درس بعد کامل یاد میگیری: grep -c '^[45]' یعنی «چند خط با ۴ یا ۵ شروع میشوند».)
مثال ۷: تمرین اصلی، ۱۰ آدرس IP پرتکرار
Section titled “مثال ۷: تمرین اصلی، ۱۰ آدرس IP پرتکرار”همهی چیزهایی که یاد گرفتی در یک pipeline:
cut -d' ' -f1 access.log | sort | uniq -c | sort -rn | head -10 1055 203.0.113.5 667 198.51.100.7 405 192.0.2.44 230 192.0.2.8 222 203.0.113.77 212 203.0.113.9 209 198.51.100.23خط به خط: cut ستون IP، sort تا یکسانها کنار هم بیایند، uniq -c تعداد، sort -rn عددی و معکوس، head -10 دهتای اول. اگر فقط ۳ تای اول خواسته بودی head -3؛ اگر فقط IP بدون عدد: انتهای pipeline | awk '{print $2}' (یا cut -c9-). برای دیدن مرحلهبهمرحله، pipeline را قطعهقطعه اجرا کن و خروجی هر مرحله را ببین (روش عیبیابی pipeline).
مثال ۸: xargs، خروجی را به argument تبدیل کن
Section titled “مثال ۸: xargs، خروجی را به argument تبدیل کن”بعضی دستورها (مثل rm، cp، mkdir) از stdin نمیخوانند؛ argument میخواهند. xargs ورودیاش را میخواند و آن را به argument های یک دستور تبدیل میکند:
mkdir -p xdemo && cd xdemoecho "a b c" | xargs touchlsecho "--- هر ورودی در یک اجرا (-n 1):"echo "x y z" | xargs -n 1 echo "پردازش:"echo "--- جایگذاری با -I:"printf 'one\ntwo\n' | xargs -I{} echo "فایل {} پردازش شد"echo "--- ترکیب با find و wc:"find . -type f | xargs wc -c | tail -1abc--- هر ورودی در یک اجرا (-n 1):پردازش: xپردازش: yپردازش: z--- جایگذاری با -I:فایل one پردازش شدفایل two پردازش شد--- ترکیب با find و wc:0 totalxargs touch سه فایل ساخت؛ -n 1 ورودیها را یکییکی میدهد؛ -I{} جای {} را با هر ورودی پر میکند. خطر اسمهای دارای فاصله:
cd xdemotouch "my file.txt"echo "--- بدون -0 (اسم با فاصله میشکند):"find . -name "my*" | xargs ls -l 2>&1 | head -2echo "--- درست: -print0 با xargs -0 (جداکنندهی NUL):"find . -name "my*" -print0 | xargs -0 ls -l | awk '{print $9, $10}'--- بدون -0 (اسم با فاصله میشکند):ls: cannot access './my': No such file or directoryls: cannot access 'file.txt': No such file or directory--- درست: -print0 با xargs -0 (جداکنندهی NUL):./my file.txtxargs پیشفرض با فاصله و خط جدید خرد میکند، پس my file.txt دو argument میشود. راه امن: find -print0 | xargs -0 (جداکنندهی بایت NUL که در اسم فایل نمیآید). و xargs -P 4 چند اجرا را موازی انجام میدهد (مثلاً فشردهسازی ۴ فایل همزمان).
مثال ۹: وضعیت خروج یک pipeline
Section titled “مثال ۹: وضعیت خروج یک pipeline”pipeline یک کد خروج دارد: کد آخرین دستور. ببین:
ls /no/such/dir 2>/dev/null | wc -lecho "کد خروج pipeline: $?"echo "--- کد خروج تکتک دستورها (PIPESTATUS):"ls /no/such/dir 2>/dev/null | wc -l >/dev/nullecho "ls=${PIPESTATUS[0]} wc=${PIPESTATUS[1]}"echo "--- با pipefail:"set -o pipefaills /no/such/dir 2>/dev/null | wc -l >/dev/nullecho "کد خروج با pipefail: $?"set +o pipefail0کد خروج pipeline: 0--- کد خروج تکتک دستورها (PIPESTATUS):ls=2 wc=0--- با pipefail:کد خروج با pipefail: 2ls خطا (۲) داد ولی چون wc موفق بود، کل pipeline 0 برگرداند: خطا گم شد! با set -o pipefail کد خروج اولین دستور ناموفق برمیگردد (برای اسکریپتهای مهم همیشه بگذار)، و PIPESTATUS کد همهی دستورها را دارد.
مثال ۱۰: دیدن وسط pipeline با tee
Section titled “مثال ۱۰: دیدن وسط pipeline با tee”cut -d' ' -f1 access.log | sort | tee sorted-ips.txt | uniq -c | sort -rn | head -3echo "--- فایل میانی ذخیره شد: $(wc -l < sorted-ips.txt) خط" 1055 203.0.113.5 667 198.51.100.7 405 192.0.2.44--- فایل میانی ذخیره شد: 3000 خطtee (درس قبل) داخل pipeline یک «بازرس» میگذارد: داده را به فایل میریزد و همزمان رد میکند. هنگام ساختن pipeline پیچیده، با tee خروجی مرحلهی میانی را ذخیره میکنی تا ببینی کجا خراب شده.
پشت پرده: pipe چطور کار میکند؟
Section titled “پشت پرده: pipe چطور کار میکند؟”وقتی A | B را مینویسی، shell یک لولهی هسته (pipe) میسازد (یک بافر کوچک در حافظهی هسته، حدود ۶۴ کیلوبایت)، دو پروسه را همزمان اجرا میکند و stdout پروسهی A را به سر نوشتن و stdin پروسهی B را به سر خواندن لوله وصل میکند. اگر B کند باشد و بافر پر شود، A منتظر میماند (back-pressure)؛ اگر لوله خالی باشد، B منتظر داده میماند. به همین دلیل میتوانی با pipe فایل ۱۰۰ گیگابایتی را پردازش کنی بدون اینکه حافظه پر شود: داده در جریان است، نه یکجا در حافظه.
نکتهی مهم: stderr وارد pipe نمیشود (فقط stdout). خطاها روی صفحه میمانند مگر 2>&1 یا |& بنویسی. و sort استثناست: چون باید همهی ورودی را ببیند تا مرتب کند، تا پایان ورودی چیزی نمیدهد؛ در حالی که head پس از گرفتن ۱۰ خط خارج میشود و A با سیگنال SIGPIPE میمیرد (نه اینکه تا آخر کار ادامه دهد). همین است که yes | head -1 تمام میشود.
جدولهای مرجع
Section titled “جدولهای مرجع”| دستور | کار | flag های مهم |
|---|---|---|
sort |
مرتبسازی | -n عددی، -r معکوس، -u یکتا، -k N ستون، -t X جداکننده، -h اعداد خوانا |
uniq |
حذف تکراریهای متوالی | -c شمارش، -d فقط تکراری، -u فقط یکتا |
cut |
برش ستون | -d جداکننده، -f ستون، -c کاراکتر |
tr |
تبدیل کاراکتر | -d حذف، -s فشرده، 'a-z' 'A-Z' |
wc |
شمارش | -l خط، -w کلمه، -c بایت |
head / tail |
ابتدا / انتها | -n N |
xargs |
تبدیل stdin به argument | -n 1، -I{}، -0، -P N |
tee |
شاخهی میانی | -a افزودن |
| الگوی رایج | کار |
|---|---|
... | sort | uniq -c | sort -rn | head |
«پرتکرارترینها» |
... | wc -l |
«چند تا؟» |
find ... -print0 | xargs -0 cmd |
اجرای امن دستور روی فایلها |
set -o pipefail |
خطای وسط pipeline را گم نکن |
اشتباهات رایج
Section titled “اشتباهات رایج”۱) uniq بدون sort
Section titled “۱) uniq بدون sort”printf 'a\nb\na\n' | uniq -c 1 a 1 b 1 aa دو بار جدا شمرده شد (۱، ۱، ۱) چون پشتسرهم نبودند. راهحل: sort | uniq -c.
۲) sort بدون -n برای عدد
Section titled “۲) sort بدون -n برای عدد”printf '9\n10\n2\n' | sort | tr '\n' ' '; echoprintf '9\n10\n2\n' | sort -n | tr '\n' ' '; echo10 2 92 9 10الفبایی: 10 2 9؛ عددی: 2 9 10. راهحل: -n برای عددها.
۳) فرض اینکه pipe خطا را هم میبرد
Section titled “۳) فرض اینکه pipe خطا را هم میبرد”ls /no/such 2>&1 | wc -lecho "---"ls /no/such | wc -l1---ls: cannot access '/no/such': No such file or directory0بدون 2>&1، پیام خطا از pipe رد نشد و روی صفحه آمد (wc عدد ۰ را دید). راهحل: 2>&1 یا |&.
۴) xargs با اسمهای دارای فاصله
Section titled “۴) xargs با اسمهای دارای فاصله”مثال ۸. راهحل: find ... -print0 | xargs -0 ....
۵) cut -d' ' روی ستونهای با فاصلهی متغیر
Section titled “۵) cut -d' ' روی ستونهای با فاصلهی متغیر”printf 'a b\nc d\n' | cut -d' ' -f2چون چند فاصله پشت هم هستند، cut ستونهای خالی میبیند و خروجی عجیب میدهد. راهحل: اول tr -s ' ' برای فشرده کردن، یا awk '{print $2}'.
از access.log تعداد کل خطها و تعداد IP های یکتا را بشمار.
دیدن جواب
echo "خطها: $(wc -l < access.log)"echo "IP یکتا: $(cut -d' ' -f1 access.log | sort -u | wc -l)"خطها: 3000IP یکتا: 7تمرین اصلی: از یک فایل لاگ، ۱۰ آدرس IP پرتکرار را پیدا کن. فایل لاگ را بساز (مثل بالا) و با یک pipeline پنجحلقهای IP های پرتکرار را با تعدادشان نشان بده، بعد نسخهای که فقط اسم IP ها (بدون عدد) را چاپ کند.
دیدن جواب
awk 'BEGIN{for(i=1;i<=500;i++) print "10.0.0." (i*i%9+1) " GET /x"}' > log.txtcut -d' ' -f1 log.txt | sort | uniq -c | sort -rn | head -10echo "--- فقط IP ها:"cut -d' ' -f1 log.txt | sort | uniq -c | sort -rn | head -10 | tr -s ' ' | cut -d' ' -f3 166 10.0.0.1 112 10.0.0.8 111 10.0.0.5 111 10.0.0.2--- فقط IP ها:10.0.0.110.0.0.810.0.0.510.0.0.2یک گزارش سهبخشی از access.log بساز با یک pipeline برای هر بخش: (۱) ۳ مسیر (path) پرتکرار (ستون ۷)، (۲) تعداد درخواستهای هر کد وضعیت، (۳) ۳ IP که بیشترین خطای ۴xx/۵xx را داشتهاند (راهنما: grep یا awk برای فیلتر کد؛ میتوانی از awk '$9 ~ /^[45]/ {print $1}' استفاده کنی).
دیدن جواب
awk 'BEGIN { split("203.0.113.5 203.0.113.5 203.0.113.5 198.51.100.7 198.51.100.7 192.0.2.44 203.0.113.9 192.0.2.8", ip, " ") split("200 200 200 404 404 500", st, " ") split("/index.html /about /api/users /login", pa, " ") for (i = 1; i <= 800; i++) printf "%s - - [x] \"GET %s HTTP/1.1\" %s 100\n", ip[(i*i+i)%8+1], pa[(i*5+int(i/9))%4+1], st[(i*3+int(i/7))%6+1]}' > a.logecho "== ۳ مسیر پرتکرار:"; cut -d' ' -f7 a.log | sort | uniq -c | sort -rn | head -3echo "== کدهای وضعیت:"; cut -d' ' -f9 a.log | sort | uniq -c | sort -rnecho "== IP های با بیشترین خطا:"; awk '$9 ~ /^[45]/ {print $1}' a.log | sort | uniq -c | sort -rn | head -3== ۳ مسیر پرتکرار: 800 HTTP/1.1"== کدهای وضعیت: 800 100== IP های با بیشترین خطا:آزمونک
Section titled “آزمونک”علامت | چه میکند؟
دو دستور همزمان اجرا میشوند.
چرا قبل از uniq -c معمولاً sort میزنیم؟
sort یکسانها را کنار هم میآورد.
sort -rn چه میکند؟
-n عددی، -r معکوس.
cut -d: -f1 /etc/passwd چه میدهد؟
-d جداکننده و -f شمارهی ستون.
xargs چه میکند؟
برای دستورهایی که از stdin نمیخوانند مثل rm.
pipeline کد خروج کدام دستور را برمیگرداند (پیشفرض)؟
با set -o pipefail خطای هر مرحله را میگیری.
جمعبندی
Section titled “جمعبندی”- pipe (
|): stdout دستور چپ → stdin دستور راست؛ دستورها همزمان اجرا میشوند و داده در جریان است. - ابزارهای کوچک:
sort(-n -r -u -k -t -h)،uniq -c،cut -d -f،tr،wc -l،head/tail،tee،xargs. - الگوی «پرتکرارترینها»:
cut ... | sort | uniq -c | sort -rn | head.uniqفقط تکرارهای متوالی را میگیرد، پسsortقبلش. xargsخروجی را argument میکند؛ برای اسمهای دارای فاصلهfind -print0 | xargs -0.- stderr وارد pipe نمیشود (مگر
2>&1یا|&)؛ کد خروج pipeline کد آخرین دستور است؛set -o pipefailوPIPESTATUS. - هنگام ساختن pipeline، مرحلهبهمرحله اجرا کن و با
teeوسط را ببین.
| دستور | کاری که میکند |
|---|---|
cmd1 | cmd2 | خروجی cmd1 → ورودی cmd2 |
sort -n / sort -rn | مرتبسازی عددی / عددی معکوس |
sort -u / sort -k2 | یکتا / بر اساس ستون ۲ |
sort | uniq -c | شمارش هر مقدار |
cut -d" " -f1 | ستون اول با جداکنندهی فاصله |
tr "a-z" "A-Z" | تبدیل به حروف بزرگ |
tr -d "\r" | حذف \r |
wc -l | تعداد خط |
cut -d" " -f1 f | sort | uniq -c | sort -rn | head | ۱۰ مقدار پرتکرار |
find . -print0 | xargs -0 cmd | اجرای امن روی فایلها |
cmd1 |& cmd2 | stdout و stderr هر دو به pipe |
set -o pipefail | خطای هر مرحله را برگردان |