فصل 16- فرمان‌ها، برنامه‌ها و فیلترهای خارجی

‎16.4‎- فرمان‌های پردازش متن

فرمان‌های مؤثر بر متن و فایل‌های متنی

sort

برنامه سودمند مرتب‌سازی فایل، بیشتر اوقات به عنوان فیلتر در یک لوله به کار می‌رود. این فرمان یک جریان متن یا فایل را به طرف جلو یا عقب یا براساس کلیدهای مختلف یا وضعیت کاراکترها مرتب می‌کند. با استفاده از گزینه ‎-m‎ فایل‌های از قبل مرتب شده را با هم ادغام می‌کند. صفحه info گزینه‌ها و امکانات بسیار آن را فهرست می‌کند. مثال ‎11-10‎، مثال ‎11-11‎، و مثال ‎A-8‎ را ببینید.

tsort

مرتب‌سازی Topological، خواندن جفت رشته‌های جداشده با فضای سفید و مرتب کردن آنها مطابق با الگوهای ورودی. هدف اولیه tsort فراهم نمودن لیستی از وابستگی‌ها برای یک نگارش منسوخ از پیونددهنده ld در یک نگارش «قدیمی» یونیکس بود.

نتایج حاصل از tsort معمولاً با نتایج حاصل از دستور استاندارد sort فوق، تفاوت محسوسی دارند.

uniq

این فیلتر سطرهای تکراری را از یک فایل مرتب‌شده حذف می‌کند. بیشتر اوقات به صورت جفت‌ شده با sort در یک لوله دیده می‌شود.

cat list-1 list-2 list-3 | sort | uniq > final.list
#              فایل‌های ‎list‎ را بهم متصل می‌کند،
#                         آنها را مرتب می‌سازد،
#                  سطرهای تکراری را حذف می‌کند،
# و سرانجام نتیجه را در یک فایل خروجی می‌نویسد.

گزینه مفید ‎-c‎ تعداد تکرار هر سطر فایل ورودی را به آن پیشوند می‌کند.

bash$ cat testfile
This line occurs only once.
This line occurs twice.
This line occurs twice.
This line occurs three times.
This line occurs three times.
This line occurs three times.


bash$ uniq -c testfile
      1 This line occurs only once.
      2 This line occurs twice.
      3 This line occurs three times.


bash$ sort testfile | uniq -c | sort -nr
      3 This line occurs three times.
      2 This line occurs twice.
      1 This line occurs only once.

رشته فرمان ‎sort INPUTFILE | uniq -c | sort -nr‎ فهرستی از فراوانی تکرارها در فایل INPUTFILE فراهم می‌کند (گزینه ‎-nr‎ برای sort باعث ترتیب عددی برعکس می‌شود). این الگو در تجزیه و تحلیل فایل‌های ثبت رخداد و فهرست واژه‌نامه‌ها، و هرجایی که لازم باشد ساختار کلمه‌ای یک سند وارسی بشود، مورد استفاده می‌یابد.

مثال ‎16-12‎. تجزیه و تحلیل فراوانی کلمه

#!/bin/bash
# ‎wf.sh: ‎ .تجزیه‌و تحلیل خام تکرار کلمه در یک فایل متن
#          این یک نسخه کارآمدتر از اسکریپت ‎wf2.sh‎ است.


#             .کنترل جهت ارایه فایل ورودی در خط فرمان
ARGS=1
E_BADARGS=85
E_NOFILE=86

if [ $# -ne "$ARGS" ]  # آیا تعداد شناسه‌های خط فرمان صحیح است؟
then
  echo "Usage: `basename $0` filename"
  exit $E_BADARGS
fi

if [ ! -f "$1" ]       #       .کنترل موجود بودن فایل
then
  echo "File \"$1\" does not exist."
  exit $E_NOFILE
fi



########################################################
# main ()
sed -e 's/\.//g'  -e 's/\,//g' -e 's/ /\
/g' "$1" | tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr
#                           =========================
#                                 تعداد تکرارها

# فیلتر کردن کاراکترهای نقطه‌ و کاما، و تعویض فاصله بین کلمات
#+  با سطر جدید، سپس تبدیل کاراکترها به حالت کوچک، و سرانجام
#+                .پیشوند کردن شماره تکرارها و مرتب‌سازی عددی

#      ‎Arun Giridhar‎ اصلاح کد فوق به این صورت را پیشنهاد می‌کند:
#  . . . | sort | uniq -c | sort +1 [-f] | sort +0 -nr
#     این یک کلید مرتب‌سازی دوم اضافه می‌کند، بنابراین نمونه‌های دارای تعداد
#+                               .تکرار مساوی، به طور الفبایی مرتب می‌شوند
#                                                :به طوری که او شرح می‌دهد
# «این یک مرتب‌سازی مبنایی کارآمد است، اول روی ستون دارای حداقل اهمیت (کلمه
#+  یا رشته، به طور دلخواه حساس به حالت حروف) و بعد روی ستون دارای بیشترین
#+                                                 اهمیت (تعداد تکرارها).»
#
#  همچنانکه ‎Frank Wang‎ توضیح می‌دهد، کد فوق معادل است با:
#+   . . . | sort | uniq -c | sort +0 -nr
#+                             و کد پایین هم کار می‌کند:
#+   . . . | sort | uniq -c | sort -k1nr -k
########################################################

exit 0

#                          :تمرین‌ها
#                         ----------
# ‎(1‎ فرمان‌های ‎sed‎ برای فیلتر کردن سایر کاراکترهای نشانه‌گذاری،
#+                          از قبیل سمی‌کالن را اضافه کنید.
#  ‎(2‎ اسکریپت را برای فیلتر کردن فاصله‌های چندتایی و سایر فضای
#+                                   سفیدها نیز ویرایش کنید.

bash$ cat testfile
This line occurs only once.
This line occurs twice.
This line occurs twice.
This line occurs three times.
This line occurs three times.
This line occurs three times.


bash$ ./wf.sh testfile
   6 this
   6 occurs
   6 line
   3 times
   3 three
   2 twice
   1 only
   1 once

expand‏، unexpand

فیلتر expand کاراکترهای tab را به فاصله تبدیل می‌کند. بیشتر اوقات در یک pipe استفاده می‌شود.

فیلتر unexpand فاصله‌ها را به tab تبدیل می‌کند. این فیلتر اثر expand را وارونه می‌کند.

cut

ابزاری برای استخراح فیلدهای فایل‌ها. مشابه فرمان ‎print $N‎ در awk، اما محدودتر است. ممکن است در اسکریپت، استفاده از cut آسان‌تر از awk باشد. گزینه‌های بویژه با اهمیت این فرمان، ‎-d‎ (جداکننده) و ‎-f‎ (مشخص‌کننده فیلد) هستند.

کاربرد cut برای به دست آوردن فهرستی از سیستم‌فایل‌های متصل‌شده:

cut -d ' ' -f1,2 /etc/mtab

کاربرد cut برای لیست کردن نگارش کرنل و سیستم‌عامل:

uname -a | cut -d" " -f1,3,11,12

کاربرد cut برای استخراج سرآیند پیغام‌ها از یک پوشه ‎e-mail‎:

bash$ grep '^Subject:' read-messages | cut -c10-80
Re: Linux suitable for mission-critical apps?
MAKE MILLIONS WORKING AT HOME!!!
Spam complaint
Re: Spam complaint

کاربرد cut برای تجزیه یک فایل:

# فهرست تمام کاربران در فایل ‎/etc/passwd‎.

FILENAME=/etc/passwd

for user in $(cut -d: -f1 $FILENAME)
do
  echo $user
done

# با تشکر از ‎Oleg Philon‎ برای این پیشنهاد.

‎cut -d ' ' -f2,3 filename‎ معادل با ‎awk -F'[ ]' '{ print $2, $3 }' filename‎ است.

حتی تعیین نمودن یک کاراکتر تعویض سطر به عنوان جداکننده، امکان‌پذیر است. در واقع ترفند آن، جاسازی تعویض سطر ‎(RETURN)‎ در رشته فرمان است.

bash$ cut -d'
 ' -f3,7,19 testfile
This is line 3 of testfile.
This is line 7 of testfile.
This is line 19 of testfile.

‎Jaka Kranjc‎ برای توضیح این مورد متشکرم.

همچنین مثال ‎16-48‎ را مشاهده نمایید.

paste

ابزاری برای ادغام فایل‌های مختلف با یکدیگر در یک فایل واحدِ چند ستونی. در ترکیب با cut، برای ایجاد فایل‌های ثبت رخداد سیستم مفید است.

bash$ cat items
alphabet blocks
building blocks
cables

bash$ cat prices
$1.00/dozen
$2.50 ea.
$3.75

bash$ paste items prices
alphabet blocks $1.00/dozen
building blocks $2.50 ea.
cables  $3.75

join

این فرمان را به عنوان یک عموزاده تک منظوره paste در نظر بگیرید. این برنامه قدرتمند، ادغام دو فایل به یک سبک معنادار را میسر می‌کند که این در اصل نگارش ساده‌ای از یک بانک اطلاعات رابطه‌ای تولید می‌کند.

فرمان join دقیقاً روی دو فایل عمل می‌کند، اما فقط سطرهای دارای یک فیلد مشترک برچسب (معمولاً برچسب عددی) را به یکدیگر وصل می‌کند، و نتیجه را در stdout می‌نویسد. فایل‌هایی که قرار است متصل شوند باید بر اساس فیلد برچسب‌ مرتب شده باشند تا یارگیری‌ها به طور صحیح انجام گردد.

File: 1.data

100 Shoes
200 Laces
300 Socks

File: 2.data

100 $40.00
200 $1.00
300 $2.00

bash$ join 1.data 2.data
File: 1.data 2.data

100 Shoes $40.00
200 Laces $1.00
300 Socks $2.00

فیلد برچسب‌ فقط یکبار در خروجی ظاهر می‌شود.


head

سطرهای ابتدای یک فایل را در stdout لیست می‌کند. پیش‌‌فرض آن ‎10‎ سطر است، اما یک عدد متفاوت نیز می‌تواند تعیین بشود. فرمان دارای تعدادی گزینه جالب توجه است.

مثال ‎16-13‎. کدام فایل‌ها اسکریپت هستند؟

#!/bin/bash
# ‎script-detector.sh:‎  .اسکریپت‌های داخل یک دایرکتوری را تشخیص می‌دهد

TESTCHARS=2    #                 .بررسی دو کاراکتر نخست
SHABANG='#!'   #  اسکریپت‌ها با یک«‎sha-bang‎» شروع می‌شوند.

for file in *  #    .پیمایش تمام فایل‌های دایرکتوری جاری
do
  if [[ `head -c$TESTCHARS "$file"` = "$SHABANG" ]]
  #      head -c2                      #!
  # گزینه ‎-c‎ با ‎head‎  به جای سطرها(پیش‌فرض) تعداد کاراکتر
  #+                            معین شده را بیرون می‌دهد.
  then
    echo "File \"$file\" is a script."
  else
    echo "File \"$file\" is *not* a script."
  fi
done
  
exit 0

#                        :تمرین‌ها
#                       ----------
#       ‎(1‎ این اسکریپت را برای دریافت یک دایرکتوری به عنوان 
#+     .شناسه اختیاری جهت جستجوی اسکریپت‌ها ویرایش کنید
#+   .(به جای آن که فقط دایرکتوری جاری را استفاده کند)
#
#   ‎(2‎ به طوری که مشخص است، این اسکریپت پاسخ «مثبت کاذب» جهت
#+     اسکریپت‌های ‎Perl‎‏، ‎awk‎‏، و سایر زبان‌های اسکریپت‌نویسی را
#                    نیز ارایه می‌دهد. این مورد را اصلاح کنید.

مثال ‎16-14‎. تولید اعداد تصادفی ده رقمی

#!/bin/bash
# ‎rnd.sh:‎ یک عدد تصادفی ده‌رقمی بیرون می‌دهد

# اسکریپت توسط ‎Stephane Chazelas‎ نوشته شده.

head -c4 /dev/urandom | od -N4 -tu4 | sed -ne '1s/.* //p'


# =================================================================== #

#                      تجزیه و تحلیل
#                     --------------

#  ‎head:‎
#                        گزینه ‎-c4‎ چهار بایت نخست را می‌گیرد.

#    ‎od:‎
#              گزینه ‎-N4‎ خروجی را به چهار بایت محدود می‌سازد.
#  گزینه ‎-tu4‎ قالب دسیمال بدون علامت برای خروجی انتخاب می‌کند.

#  ‎sed:‎ 
# گزینه ‎-n‎ در ترکیب با نشانه ‎p‎ برای فرمان ‎s‎ فقط سطرهای منطبق
#                                        شده را بیرون می‌دهد.



#         مؤلف این اسکریپت عمل ‎sed‎ را به صورت زیر شرح می‌دهد.

# head -c4 /dev/urandom | od -N4 -tu4 | sed -ne '1s/.* //p'
# ----------------------------------> |

# فرض کنید خروجی تا رسیدن به ‎sed‎ ---> |‎
# باشد ‎0000000 1198195154\n‎

#    ‎sed‎ شروع به خواندن کاراکترها می‌کند: ‎0000000 1198195154\n‎
#    در اینجا یک کاراکتر سطرجدید پیدا می‌کند، بنابراین آماده
#+                 پردازش سطر نخست ‎(0000000 1198195154)‎ است.
#         به ‎<محدوده>‎‎<عمل>‎هایش نگاه می‌کند. اول و فقط یکی است

#   عمل     محدوده
#   1         s/.* //p

#      شماره سطر در محدوده است، پس عمل را اجرا می‌کند:
#+  به تعویض کردن بلندترین رشته در سطر که با یک فاصله
#  پایان یافته ‎("0000000 ")‎، با هیچ ‎(//)‎ اقدام می‌کند،
#    و اگر موفق شود نتیجه را چاپ می‌کند (در اینجا ‎p‎ یک‎
#+    نشانگر جهت فرمان ‎s‎ است، با فرمان ‎p‎ تفاوت دارد).

#   اکنون ‎sed‎ آماده ادامه خواندن ورودی‌اش می‌باشد (توجه
#+      کنید که اگر گزینه ‎-n‎ داده نشده بود ‎sed‎ قبل از
#+            ادامه، یکبار دیگر سطر را چاپ کرده بود).

#  اکنون، ‎sed‎ باقیمانده کاراکترها را می‌خواند، و انتهای
#+                                فایل را تشخیص می‌دهد.
#  حال آماده پردازش سطر دوم خوانده شده است (که با ‎$‎ به
#+                      عنوان آخرین سطر شماره‌دار است).
#  مشاهده می‌کند با هیچ ‎<محدوده>‎ای منطبق نیست، بنابراین
#+                             کارش انجام گردیده است.
#                      به طور خلاصه این فرمان ‎sed‎ یعنی:
#«فقط در سطر اول، هر کاراکتری تا رسیدن به سمت راست‌ترین
#+          فاصله را حذف کرده، آنوقت آن را چاپ نماید.»

#  روش مناسب‌تری برای انجام این کار می‌توانست چنین باشد:
#           sed -e 's/.* //;q'

#   در اینجا، دو  ‎<محدوده>‎‎<عمل>‎ (می‌تواند
#  نوشته شود      ‎sed -e 's/.* //' -e q‎):

#       عمل               محدوده
#   هیچ(مطابقت سطر)‏       s/.* //
#   هیچ(مطابقت سطر)‏       q (quit)

# در اینجا، ‎sed‎ فقط اولین سطر ورودی‌اش را می‌خواند. هر دو
# عمل را انجام می‌دهد، و قبل از خروج سطر(جایگزین شده) را
#+  (به دلیل عمل ‎q‎) چاپ می‌کند، چون گزینه ‎-n‎ داده نشده.

# =================================================================== #

# یک جایگزین ساده‌تر برای اسکریپت یک سطری فوق، این است:
#           head -c4 /dev/urandom| od -An -tu4

exit

همچنین مثال ‎16-39‎ را ملاحظه نمایید.

tail

سطرهای انتهای یک فایل را در stdout لیست می‌کند. پیش‌فرض آن ‎10‎ سطر است، اما می‌تواند با گزینه ‎-n‎ تغییر کند. به طور معمول برای پیگردی تغییرات یک فایل ثبت وقایع سیستم، با گزینه ‎-f‎ به کار می‌رود، که سطرهای پیوست شده به فایل را بیرون می‌دهد.

مثال ‎16-15‎. کاربرد tail برای دیده‌بانی ثبت وقایع سیستم

#!/bin/bash

filename=sys.log

cat /dev/null > $filename; echo "Creating / cleaning out file."
# اگر فایل از قبل وجود نداشته باشد آن را ایجاد می‌کند،
#+     و اگر موجود باشد آن را به طول صفر کوتاه می‌کند.
#       ‎: > filename‎   و   ‎> filename‎ نیز کار می‌کند.

tail /var/log/messages > $filename  
# برای این کار مجوز خواندن ‎/var/log/messages‎ باید همگانی باشد.

echo "$filename contains tail end of system log."

exit 0

tip

برای لیست کردن یک سطر خاصِ یک فایل متن، خروجی فرمان head را به فرمان tail ‎-n 1‎ لوله‌کشی کنید. برای مثال، head -n 8 database.txt | tail -n 1 سطر هشتم از فایل database.txt را لیست می‌کند.

برای تنظیم یک متغیر به یک بلوک مفروض از یک فایل متن:

var=$(head -n $m $filename | tail -n $n)

# ‎filename =‎ نام فایل
# ‎m =‎ تعداد سطرها از ابتدای فایل، تا انتهای بلوک
# ‎n =‎ تعداد سطرهای بلوک (برای برش بلوک از انتها)‏


پیاده‌سازی‌های جدیدتر tail کاربرد قدیمی‌تر ‎tail -$LINES filename‎ را ناپسند می‌دانند. ‎tail -n $LINES filename‎ استاندارد، صحیح است.

همچنین مثال ‎16-5‎، مثال ‎16-39‎ و مثال ‎32-6‎ را مشاهده نمایید.

grep

یک ابزار جستجوی فایل چند منظوره است که عبارت‌های منظم را به کار می‌برد. در آغاز یک فرمان-فیلتر در ویرایشگر خطی قدیمی و پر ارزش ed بود: ‎g/re/p‎ از global - regular expression - print‎ اخذ گردیده است.

grep pattern [file...]

فایل(های) مقصد را برای موارد پیدایش pattern جستجو می‌کند، که در آن pattern می‌تواند متن لفظی یا عبارت منظم باشد.

bash$ grep '[rst]ystem.$' osinfo.txt
The GPL governs the distribution of the Linux operating system.

اگر فایل(های) مقصد تعیین نشده باشد، grep به صورت یک فیلتر بر روی stdout عمل می‌کند، همچنانکه در یک pipe عمل می‌کند.

bash$ ps ax | grep clock
765 tty1     S      0:00 xclock
901 pts/1    S      0:00 grep clock

گزینه ‎-i‎ موجب جستجوی حساس به حالت حروف می‌گردد.

گزینه ‎-w‎ فقط کلمه‌های کامل را مطابقت می‌دهد.

گزینه ‎-l‎ فقط فایل‌هایی را که در آنها مورد انطباقی پیدا شده باشد، لیست می‌کند، اما سطرهای انطباق را لیست نمی‌کند.

گزینه ‎-r‎ (بازگشت) فایل‌های دایرکتوری کاری جاری و تمام دایرکتوری‌های فرعی تحت آن را جستجو می‌نماید.

گزینه ‎-n‎ سطرهای انطباق را به همراه شماره سطرها لیست می‌کند.

bash$ grep -n Linux osinfo.txt
2:This is a file containing information about Linux.
6:The GPL governs the distribution of the Linux operating system.

گزینه ‎-v‎ (یا ‎--invert-match‎) موارد انطباق را فیلتر می‌کند.

grep pattern1 *.txt | grep -v pattern2

# تمام سطرهای فایل‌های ‎"*.txt"‎ را که شامل ‎"pattern1"‎ باشند،
#                اما شامل ‎"pattern2"‎ «نباشند»، لیست می‌کند.

گزینه ‎-c‎ ‏(‎--count‎) به جای لیست واقعی موارد انطباق، شمارش عددی مطابقت‌ها را ارایه می‌کند.

grep -c txt *.sgml   # (تعداد موارد وجود ‎txt‎ در فایل‌های ‎*.sgml‎)


#   grep -cz .
#            نقطه  ‎^‎  
#  یعنی شمارش ‎(-c)‎ موارد جداشده با بایت صفر ‎(-z)‎ منطبق با ‎"."‎‎
#    یعنی سطرهایی که تهی نیستند (شامل حداقل یک کارکتر هستند).
# 
printf 'a b\nc  d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -cz .      # 4
printf 'a b\nc  d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -cz '$'    # 5
printf 'a b\nc  d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -cz '^'    # 5
#
printf 'a b\nc  d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -c '$'     # 9
# به طور پیش‌فرض، کاراکترهای سطرجدید ‎(\n)‎ اقلام را جهت انطباق جدا می‌کنند. 

# توجه نمایید که گزینه ‎-z‎ مختص grep گنو است.


#  با تشکر از ‎S.C.‎

گزینه ‎--color‎ (یا ‎--colour‎) رشته انطباق را به صورت رنگی علامت می‌زند (در کنسول یا در یک پنجره xterm). چون grep هر سطر کامل شامل الگوی انطباق را بیرون می‌دهد، این به شما امکان می‌دهد به طور دقیق آنچه را که مطابقت داده می‌شود مشاهده نمایید. همچنین گزینه ‎-o‎ را که فقط قسمت منطبقِ سطر(ها) را نشان می‌دهد، ملاحظه نمایید.

مثال ‎16-16‎. نمایش دادن سطرهای From در یک لیست مرتب‌شده پیغام‌های ‎e-mail‎

#!/bin/bash
# from.sh

#       برنامه سودمند ‎'from'‎ در سولاریس، ‎BSD‎ وغیره را شبیه‌سازی می‌نماید.
# سطر سرآیند ‎"From"‎ تمام پیغام‌های دایرکتوری ایمیل شما را بازتاب می‌دهد.


MAILDIR=~/mail/*               #               نقل‌قول نکردن متغیر. چرا؟
#    احتمالا کنترل که آیا ‎$MAILDIR‎ موجود است:   . . . ‎if [ -d $MAILDIR ]‎
GREP_OPTS="-H -A 5 --color"    #     نمایش فایل، بعلاوه سطرهای اضافی متن
                               #+      و نشان دادن ‎"From"‎ به صورت رنگی.
TARGETSTR="^From"              #                  ‎"From"‎ در ابتدای سطر.

for file in $MAILDIR           #                    نقل‌قول نکردن متغیر.
do
  grep $GREP_OPTS "$TARGETSTR" "$file"
  #    ^^^^^^^^^^              # یکبار دیگر، این متغیر را نقل‌قول نکنید.
  echo
done

exit $?

# ممکن است مایل باشید خروجی این اسکریپت را به ‎'more'‎ لوله‌کشی
#+        نمایید، یا آن را به یک فایل تغییر مسیر بدهید . . .

grep موقعی که با بیش از یک فایل مقصد معین فراخوانی شده باشد، مشخص می‌کند که کدام فایل شامل موارد انطباق‌ است.

bash$ grep Linux osinfo.txt misc.txt
osinfo.txt:This is a file containing information about Linux.
osinfo.txt:The GPL governs the distribution of the Linux operating system.
misc.txt:The Linux operating system is steadily gaining in popularity.


tip

موقع جستجوی فقط یک فایل مقصد، برای وادار نمودن grep به نمایش نام فایل، به سادگی ‎/dev/null‎ را به عنوان فایل دوم به آن بدهید.

bash$ grep Linux osinfo.txt /dev/null
osinfo.txt:This is a file containing information about Linux.
osinfo.txt:The GPL governs the distribution of the Linux operating system.

اگر یک انطباق موفق وجود داشته باشد، grep یک وضعیت خروج ‎0‎ برگشت می‌دهد، که مخصوصاً در آمیزش با گزینه ‎-q‎ جهت موقوف نمودن خروجی، آنرا برای بررسی یک شرط در اسکریپت سودمند می‌سازد.

SUCCESS=0                     #                     اگر جستجوی ‎grep‎ موفق باشد
word=Linux
filename=data.file

grep -q "$word" "$filename"   #گزینه ‎-q‎ باعث می‌شود چیزی در خروجی منعکس نگردد
                               
if [ $? -eq $SUCCESS ]
#          ‎if grep -q "$word" "$filename"‎ می‌تواند جایگزین سطرهای ‎5‎ تا ‎7‎ بشود.
then
  echo "$word found in $filename"
else
  echo "$word not found in $filename"
fi

مثال ‎32-6‎ چگونگی به کار بردن grep را برای جستجوی یک الگوی کلمه در فایل ثبت رخداد سیستم نمایش می‌دهد.

مثال ‎16-17‎. شبیه‌سازی grep در یک اسکریپت

#!/bin/bash
#  ‎grp.sh:‎            ‎grep‎ دوباره‌پیاده‌سازی ابتدایی

E_BADARGS=85

if [ -z "$1" ]        #  .کنترل وجود شناسه اسکریپت
then
  echo "Usage: `basename $0` pattern"
  exit $E_BADARGS
fi  

echo

for file in *         # ‎$PWD‎ پیمایش تمام فایل‌ها در
do
  output=$(sed -n /"$1"/p $file)  #.جایگزینی فرمان

  if [ ! -z "$output" ]           # اگر ‎"$output"‎ نقل‌قولی نباشد چه می‌شود؟
  then
    echo -n "$file: "
    echo "$output"
  fi                  # ‎sed -ne "/$1/s|^|${file}: |p"‎ معادل مورد فوق است.

  echo
done  

echo

exit 0

#                            :تمرین‌ها
# ----------------------------------------------------------
# ‎(1‎ افزودن تعویض سطر به خروجی، اگر در فایل‌(ها)، بیش از یک مورد انطباق باشد.
#                                                         ‎(2‎ افزودن ویژگی‌ها. 

چگونه grep می‌تواند برای دو (یا بیشتر) الگوی جداگانه جستجو نماید؟ اگر شما بخواهید grep تمام سطرهای یک فایل یا فایل‌هایی را که شامل هر دو الگوی ‎"pattern1"‎ و ‎"pattern2"‎ هستند نمایش بدهد چطور؟

یک روش لوله‌کشی نتیجه ‎grep pattern1‎ به ‎grep pattern2‎ است.

برای مثال، فایل زیر معلوم است:

# Filename: tstfile

This is a sample file.
This is an ordinary text file.
This file does not contain any unusual text.
This file is not unusual.
Here is some text.

اکنون، بیایید این فایل را برای سطرهای شامل هر دو کلمه «file» و «text» جستجو کنیم . . .

bash$ grep file tstfile
# Filename: tstfile
This is a sample file.
This is an ordinary text file.
This file does not contain any unusual text.
This file is not unusual.

bash$ grep file tstfile | grep text
This is an ordinary text file.
This file does not contain any unusual text.

اکنون یک سرگرمی جالب با استفاده از ‎grep . . .

مثال ‎16-18‎. حل کننده پازل جدول کلمات

#!/bin/bash
# cw-solver.sh
#                در واقع این یک لفاف در اطراف یک کد تک‌سطری است (سطر ‎46‎).

#                               بازی حل‌کننده پازل جدول کلمات و تحریف لغت.
#         شما «بعضی» از حروف در یک کلمه را که در جستجوی آن هستید، می‌دانید
#+      بنابراین به لیستی از تمام کلمات معتبر شامل حروف شناخته در محل‌های
#+                                                   معین، احتیاج دارید.
#                                                   برای مثال: ‎w...i....n‎
#                                                           1???5????10
# ‎w‎ در موقعیت ‎1‎‏، ‎3‎ حرف ناشناخته، ‎i‎ در مکان پنجم، ‎4‎ ناشناخته، ‎n‎ در انتها.
#                             (توضیحات در انتهای اسکریپت را ملاحظه کنید.)


E_NOPATT=71
DICT=/usr/share/dict/word.lst
#                    ‎^^^^^^^^‎  .جستجوی لغت در این فایل
#               لیست کلمه‌های ‎ASCII‎، یک کلمه در هر سطر.
#     اگر شما به یک لیست مناسب احتیاج دارید، بسته لیست
#+  کلمات ‎"yawl"‎ نگارنده در آدرس زیر را دانلود نمایید.
#  http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
#                             یا از 
#                http://bash.deta.in/yawl-0.3.2.tar.gz


if [ -z "$1" ]   #     اگر الگوی کلمه به عنوان یک شناسه
then             #+    خط فرمان تعیین نگردیده است . . .
  echo           #+                  . . . آنوقت . . .
  echo "Usage:"  #+                  پیغام نحوه کاربرد.
  echo
  echo ""$0" \"pattern,\""
  echo "where \"pattern\" is in the form"
  echo "xxx..x.x..."
  echo
  echo "The x's represent known letters,"
  echo "and the periods are unknown letters (blanks)."
  echo "Letters and periods can be in any position."
  echo "For example, try:   sh cw-solver.sh w...i....n"
  echo
  exit $E_NOPATT
fi

echo
# ==================================================
#   .این آنجاست که تمام کار انجام می‌شود
grep ^"$1"$ "$DICT"   #!بله، فقط یک سطر
#    |    |
#    ‎^‎   مهار شروع کلمه عبارت منظم است.
#    ‎$‎  مهار پایان کلمه عبارت منظم است.

#       ‎From _Stupid Grep Tricks‎، جلد اول، کتابی از
#+ مولف راهنمای ‎ABS‎ که ممکن است باز هم فرصتی برای 
#+ نوشتن به دست آورد ‎. . .‎ یکی از این روزها ‎. . .‎
# ==================================================
echo


exit $?  #  .اسکریپت در اینجا خاتمه می‌یابد
# اگر لغات تولید شده بسیار زیادی وجود دارد
#+   .خروجی را به یک فایل تغییر مسیر بدهید

bash$  sh cw-solver.sh w...i....n

wellington
workingman
workingmen

e‎grep‏ -- grep توسعه‌یافته -- همانند ‎grep -E است. این فرمانِ تا اندازه‌ای متفاوت، از مجموعه توسعه‌یافته عبارت‌های منظم استفاده می‌کند، که می‌تواند جستجو را مقداری قابل انعطاف‌تر نماید. همچنین استفاده از عملگر بولی | (یا) را مجاز می‌کند.

bash $ egrep 'matches|Matches' file.txt
Line 1 matches.
Line 3 Matches.
Line 4 contains matches, but also Matches

f‎grep‏ -- grep سریع -- همانند e‎grep -F است. یک جستجوی لفظی رشته (نه عبارتهای منظم) انجام می‌دهد، که به طورکلی مقدار کمی به کارها سرعت می‌بخشد.

در برخی توزیع‌های لینوکس، e‎grep و f‎grep پیوندهای نمادین یا مستعارهایی برای ‎grep ، اما به ترتیب فراخوانی شده با گزینه‌های ‎-E‎ و ‎-F‎ هستند.

مثال ‎16-19‎. جستجوی تعریف‌ها در فرهنگ لغت ‎Webster's 1913

#!/bin/bash
# dict-lookup.sh

# این اسکریپت تعریف‌ها را در فرهنگ لغت  ‎1913 Webster‎ جستجو می‌کند.
#این فرهنگ لغت همگانی در سایت‌های مختلفی جهت دانلود در دسترس است،
#+   از جمله پروژه گوتنبرگ ‎(http://www.gutenberg.org/etext/247)‎.
#
# قبل از به کار بردن آن با این اسکریپت، آن را از قالب ‎DOS‎ به ‎UNIX‎
#+                  (فقط کاراکتر ‎LF‎ در انتهای سطر) تبدیل نمایید.
#          فایل را در قالب متن اسکی ساده متراکم نشده ذخیره کنید.
#متغیر ‎DEFAULT_DICTFILE پایین را به مسیر حضور فایل تنظیم نمایید.


E_BADARGS=85
MAXCONTEXTLINES=50             #   . حداکثر تعداد سطر برای نمایش
DEFAULT_DICTFILE="/usr/share/dict/webster1913-dict.txt"
                               #   .نام مسیر پیش‌فرض فایل دیکشنری
                               #.در صورت لزوم این را تغییر بدهید
#                  :توجه
# --------------------------------------
#      در این ویرایش خاص از ‎1913 Webster‎
#+هر مدخل با یک حرف ‎uppercase‎ شروع می‌شود
#+      (حروف کوچک برای بقیه کاراکترها).
#فقط «سطر اول واقعی» هر مدخل به این صورت
#+شروع می‌شود، و بدین علت الگوریتم جستجوی
#                       پایین کار می‌کند.


if [[ -z $(echo "$1" | sed -n '/^[A-Z]/p') ]]
# حداقل باید کلمه‌ای برای جستجو مشخص شود، و
#+  .آن کلمه باید با یک حرف بزرگ آغاز بشود
then
  echo "Usage: `basename $0` Word-to-define [dictionary-file]"
  echo
  echo "Note: Word to look up must start with capital letter,"
  echo "with the rest of the word in lowercase."
  echo "--------------------------------------------"
  echo "Examples: Abandon, Dictionary, Marking, etc."
  exit $E_BADARGS
fi


if [ -z "$2" ]          #  امکان این هست که یک دیکشنری متفاوت به
                        #+   .عنوان شناسه این اسکریپت تعیین گردد
then
  dictfile=$DEFAULT_DICTFILE
else
  dictfile="$2"
fi

# --------------------------------------------------------------
Definition=$(fgrep -A $MAXCONTEXTLINES "$1 \\" "$dictfile")
#                                      ‎"Word \..."‎ تعاریف به شکل
#
#بله، ‎fgrep‎ برای جستجوی حتی یک فایل متن بزرگ به حد کافی سریع است


#            .اکنون، فقط بیرون کشیدن بلوک تعریف

echo "$Definition" |
sed -n '1,/^[A-Z]/p' |
#.چاپ از اولین سطر خروجی تا اولین سطر مدخل بعدی
sed '$d' | sed '$d'
#.حذف دو سطر آخر خروجی (سطر خالی و سطر مدخل بعد)
# --------------------------------------------------------------

exit $?

#                       :تمرین‌ها
# ----------------------------------------------------
#         ‎(1‎ اسکریپت را برای پذیرش هر نوع ورودی الفبایی
#            (حروف بزرگ، کوچک، و متداخل) و تبدیل آن به 
#              قالب مورد قبول برای پردازش، ویرایش کنید.
#
# ‎(2  با استفاده از چیزی مانند ‎gdialog‎ یا ‎zenity‎ و غیره
#        اسکریپت را به یک برنامه کاربردی ‎GUI‎ تبدیل کنید
#        آنوقت، اسکریپت دیگر شناسه‌ یا شناسه‌های خط فرمان
#                                    قبول نخواهد کرد.
#
# ‎(3  اسکریپت را برای تجزیه یکی دیگر از فرهنگ‌های همگانی
#      از قبیل ‎U.S. Census Bureau Gazetteer‎ ویرایش کنید.

همچنین برای یک نمونه از جستجوی سریع f‎grep روی یک فایل متن بزرگ، مثال ‎A-41‎ را مشاهده نمایید.

a‎grep ‏(‎approximate grep‎) توانایی‌های ‎grep را به انطباق تقریبی گسترش می‌دهد. رشته جستجو ممکن است بواسطه تعداد معینی از کاراکترها با انطباق‌های حاصله تفاوت داشته باشد. این برنامه سودمند، بخشی از هسته مرکزی توزیع لینوکس نیست.

tip

برای جستجوی فایل‌های فشرده، z‎grep‏، ze‎grep‏، یا zf‎grep را به کار ببرید. اینها روی فایل‌های غیرفشرده نیز کار می‌کنند، اگرچه آهسته‌تر از ‎grep‏، e‎grep‏، f‎grep ساده. آنها برای جستجو در میان یک مجموعه مختلط فایل‌ها، برخی فشرده و بعضی غیر فشرده، سودمند هستند.

برای جستجو در فایل‌های bzip شده، از bz‎grep استفاده نمایید.


look

فرمان look مانند grep کار می‌کند، اما جستجویی روی یک «فرهنگ لغت»، یک لیست مرتب‌شده کلمات، انجام می‌دهد. به طور پیش‌فرض، look جهت یک انطباق در ‎/usr/dict/words‎ جستجو می‌کند، اما یک فایل فرهنگ لغت متفاوت نیز می‌تواند تعیین بشود.

مثال ‎16-20‎. کنترل کلمات در یک لیست برای تصدیق اعتبار

#!/bin/bash
#  ‎lookup:‎ .یک جستجوی فرهنگ لغت برای هر کلمهِ یک فایل داده‌ای انجام می‌دهد

file=words.data  # .فایل داده‌ای که کلمات مورد بررسی از آن خوانده می‌شوند

echo
echo "Testing file $file"
echo

while [ "$word" != end ]    
do               # ^^^      # .آخرین کلمه در فایل داده‌ها
  read word      #    .به علت تغییر مسیر در انتهای حلقه، از فایل داده‌ها می‌خواند
  look $word > /dev/null    #         .نمایش سطرهای فایل فرهنگ لغت را نمی‌خواهید
                            # لغات را در فایل ‎/usr/share/dict/words‎ جستجو می‌کند.
                            #+      (که معمولاً یک پیوند به فایل ‎linux.words‎ است).
  lookup=$?                 #                             وضعیت خروج فرمان ‎look‎.
 
  if [ "$lookup" -eq 0 ]
  then
    echo "\"$word\" is valid."
  else
    echo "\"$word\" is invalid."
  fi  

done <"$file"   # ‎stdin‎ را به ‎$file‎ تغییر مسیر می‌دهد، بنابراین از اینجا می‌خواند.

echo

exit 0

# ----------------------------------------------------------
#                به علت فرمان ‎exit‎ فوق، کد زیر اجرا نمی‌شود.


# ‎Stephane Chazelas‎ جایگزین مختصرتر پایین را پیشنهاد می‌کند:

while read word && [[ $word != end ]]
do if look "$word" > /dev/null
   then echo "\"$word\" is valid."
   else echo "\"$word\" is invalid."
   fi
done <"$file"

exit 0

‎sed‎‏، ‎awk‎

زبان‌های اسکریپت‌نویسی بویژه مناسب برای تجزیه فایل‌های متن و خروجی فرمان. می‌توانند به تنهایی یا با یکدیگر در لوله‌ها و اسکریپت‌های پوسته تعبیه بشوند.

sed

«ویرایشگر جریانی» غیر محاوره‌ای، به کار بردن بسیاری از فرمانهای ex‎ را در وضعیت دسته‌ای مجاز می‌کند. در اسکریپت‌های پوسته مورد استفاده بسیاری پیدا می‌کند.

awk

استخراج کننده و قالب‌دهنده فایل قابل برنامه‌نویسی، مناسب برای دستکاری و/یا استخراج فیلدها (ستون‌ها) در فایل‌های متن ساخت‌یافته. ترکیب دستوری آن مشابه با زبان ‎C‎ است.

wc

wc یک «شمارش کلمه» بر روی فایل یا جریان ورودی-خروجی ارایه می‌کند:

bash $ wc /usr/share/doc/sed-4.1.2/README
13  70  447 README
[13 lines  70 words  447 characters]

wc -w‎ فقط شمارش کلمات را ارایه می‌کند.

wc -l‎ فقط شمارش سطر را ارایه می‌کند.

wc -c‎ فقط شمارش بایت را ارایه می‌کند.

wc‎ -m‎ فقط شمارش کاراکتر را ارایه می‌کند.

wc‎ -L‎ فقط طول بلندترین سطر را ارایه می‌کند.

کاربرد wc برای شمردن آن که چند فایل ‎.txt‎ در دایرکتوری کاری جاری وجود دارد:

$ ls *.txt | wc -l
#   به شرط اینکه هیچ یک از فایل‌های ‎*.txt‎ دارای سطر جدید
#+              .جاسازی شده در نامشان نباشند کار می‌کند

#             روش‌های جایگزین انجام این کار عبارتند از:
# find . -maxdepth 1 -name \*.txt -print0 | grep -cz .
#           (shopt -s nullglob; set -- *.txt; echo $#)

#   با تشکر از ‎S.C.‎

استفاده از wc برای جمع زدن اندازه فایل‌هایی که نامشان با حروف محدوده ‎d - h‎ شروع می‌شود:

bash$ wc [d-h]* | grep total | awk '{print $3}'
71832

استفاده از wc برای شمردن موارد حضور کلمه «Linux» در فایل منبع اصلی این کتاب.

bash$ grep Linux abs-book.sgml | wc -l
138

همچنین مثال ‎16-39‎ و مثال ‎20-8‎ را مشاهده نمایید.

برخی فرمان‌ها، قابلیت‌هایی از wc را به صورت گزینه در خود دارند.

... | grep foo | wc -l
# این ساختار مورد استفاده مکرر، می‌تواند به طور خلاصه‌تری ارایه شود.

... | grep -c foo
#            فقط با استفاده از گزینه ‎-c‎ (یا ‎--count‎) برنامه ‎grep‎.

#   با تشکر از ‎S.C.‎

tr

فیلتر ترجمه کاراکتر.

Caution

باید از نقل‌قول و/یا براکت‌ها، به طور مناسب استفاده شود. نقل‌قول‌هاپوسته را از تفسیر کاراکترهای خاص در رشته‌های فرمان tr باز می‌دارند. براکت‌ها برای پیشگیری از بسط یافتن توسط پوسته، باید نقل‌قولی بشوند.

هر کدام از ‎tr "A-Z" "*" <filename‎ یا ‎tr A-Z \* <filename‎ تمام حروف بزرگ در filename را به ستاره تغییر می‌دهند (در stdout می‌نویسند). این ممکن است در برخی سیستم‌ها کار نکند، اما ‎tr A-Z '[**]'‎ کار می‌کند.

گزینه ‎-d‎ کاراکترهای یک محدوده را حذف می‌کند.

echo "abcdef"                 # abcdef
echo "abcdef" | tr -d b-d     # aef


tr -d 0-9 <filename
# تمام ارقام را از فایل ‎filename‎ حذف می‌کند.

گزینه ‎--squeeze-repeats‎ (یا ‎-s‎) غیر از مورد اول، بقیه کاراکترها در رشته‌ای از کاراکترهای متوالی (م: کاراکترهای متوالی یکسان) را حذف می‌کند. این گزینه برای حذف فضای سفید اضافی سودمند است .

bash$ echo "XXXXX" | tr --squeeze-repeats 'X'
X

گزینه ‎-c‎ ‏(complement) مجموعه کاراکتر برای انطباق را وارونه می‌کند. با این گزینه، فرمان tr فقط بر روی آن کاراکترهایی که با مجموعه مشخص شده مطابقت نمی‌کنند، عمل می‌نماید.

bash$ echo "acfdeb123" | tr -c b-d +
+c+d+b++++

توجه نمایید که tr کلاس‌های کاراکتر POSIX‏  را تشخیص می‌دهد.‎[1]‎

bash$ echo "abcd2ef1" | tr '[:alpha:]' -
----2--1

مثال ‎16-21‎‏. toupper: تبدیل تمام کاراکترهای یک فایل به حروف بزرگ.

#!/bin/bash
#       یک فایل را تماماً به حروف بزرگ تغییر می‌دهد.

E_BADARGS=85

if [ -z "$1" ]  # .کنترل مقرر برای شناسه خط فرمان
then
  echo "Usage: `basename $0` filename"
  exit $E_BADARGS
fi  

tr a-z A-Z <"$1"

#  همان نتیجه بالا، اما با استفاده ازنشانه‌گذاری مجموعه کاراکتر ‎POSIX‎:
#        tr '[:lower:]' '[:upper:]' <"$1"
#   با تشکر از ‎S.C.‎

#                   یا حتی . . .
#        cat "$1" | tr a-z A-Z
#  یا یک دوجین روش‌های دیگر . . .

exit 0

#                       تمرین‌ها
#    این اسکریپت را برای قبول گزینه‌ای جهت تغییر دادن یک
#+  .فایل یا به حروف بزرگ یا به حروف کوچک بازنویسی کنید
# اشاره: از یکی از فرمان‌های ‎case‎ یا ‎select‎ استفاده کنید.

مثال ‎16-22‎‏. lowercase: نام تمام فایل‌ها در دایرکتوری کاری را به حروف کوچک تبدیل می‌کند.

#!/bin/bash
#
#      .هر نام فایل در دایرکتوری کاری را تماماً به حروف کوچک تغییر می‌دهد
#
#                   الهام گرفته از اسکریپت نوشته ‎John Dubois‎، که به وسیله
#+                    ‎Chet Ramey‎ به داخل ‎Bash‎ منتقل گردیده بود، و به طور
#+                قابل ملاحظه‌ای توسط نگارنده راهنمای ‎ABS‎ ساده‌سازی گردیده.


for filename in *                #       .پیمایش تمام فایلهای دایرکتوری
do
   fname=`basename $filename`
   n=`echo $fname | tr A-Z a-z`  #              .تغییر نام به حروف کوچک
   if [ "$fname" != "$n" ]       #.فقط تغییر آنها که از قبل کوچک نیستند
   then
     mv $fname $n
   fi  
done   

exit $?


#                     به علت ‎exit‎ فوق، کد زیر این سطر اجرا نخواهد گردید.
#----------------------------------------------------------------------#
#                           برای اجرای آن، اسکریپت بالای سطر را حذف کنید.

#        اسکریپت فوق روی نام‌فایلهای شامل فاصله و سطرجدید عمل نخواهد کرد.
#           بدین علت ‎Stephane Chazelas‎  جایگزین پایین را پیشنهاد می‌کند:


for filename in *     #               نیازی به استفاده از basename نیست،
                      #       چون ‎*‎ هیچ نام فایل شامل ‎/‎ را برگشت نمی‌دهد.
do n=`echo "$filename/" | tr '[:upper:]' '[:lower:]'`
                      #                  نشانه‌گذاری مجموعه کاراکتر ‎POSIX‎
                      #        کاراکتر ‎/‎ اضافه شده است برای اینکه سطرهای 
                      #         جدید دنباله با جایگزینی فرمان حذف نشوند.
                      #                                  جایگزینی متغیر:
   n=${n%/}           #       ‎/‎ اضافه شده فوق از آخر نام فایل حذف می‌شود.
   [[ $filename == $n ]] || mv "$filename" "$n"
                      #   کنترل می‌کند آیا نام فایل از قبل حروف کوچک است.
done

exit $?

مثال ‎16-23‎.‏ du: تبدیل فایل متن ‎DOS‎ به یونیکس.

#!/bin/bash
# ‎Du.sh:‎  به یونیکس ‎DOS‎ تبدیل‌کنند فایل متن

E_WRONGARGS=85

if [ -z "$1" ]
then
  echo "Usage: `basename $0` filename-to-convert"
  exit $E_WRONGARGS
fi

NEWFILENAME=$1.unx

CR='\015'  #                          .کاراکتر سر سطر رفتن
           #                ‎015‎ مقدار اکتال کد اسکی ‎CR‎ است.
           #     سطرها در فایل متن ‎DOS‎ به ‎CR-LF‎ ختم می‌شوند.
           # سطرها در فایل متن یونیکس فقط به ‎LF‎ ختم می‌شوند.

tr -d $CR < $1 > $NEWFILENAME
           #                    حذف ‎CRها و نوشتن فایل جدید.

echo "Original DOS text file is \"$1\"."
echo "Converted UNIX text file is \"$NEWFILENAME\"."

exit 0

#                           :تمرین
#                          --------
# اسکریپت فوق را برای تبدیل از یونیکس به ‎DOS‎ تغییر بدهید.

مثال ‎16-24‎.‏ rot13: رمزی‌سازی فوق ضعیف.

#!/bin/bash
#  ‎rot13.sh‎:  الگوریتم رمزدار کردن ‎rot13‎ کلاسیک، که 
# .شاید یک کودک سه ساله را مدت ده دقیقه فریب بدهد

#                نحوه استعمال: ‎./rot13.sh filename‎
#                         یا  ‎./rot13.sh <filename‎
#        یا  ‎./rot13.sh‎ و ارایه ورودی از صفحه کلید

cat "$@" | tr 'a-zA-Z' 'n-za-mN-ZA-M'   # تبدیل ‎a‎ به ‎n‎، و ‎b‎ به ‎o‎ و ‎...‎
#     ساختار ‎cat "$@"‎ دریافت ورودی از فایل یا از stdin را اجازه می‌دهد.

exit 0

مثال ‎16-25‎. تولید پازل‌های «Crypto-Quote»

#!/bin/bash
# ‎crypto-quote.sh:‎ رمزی کردن نقل‌قول‌ها

# نقل‌قول‌های معروف را با یک جایگزینی الفبایی واحد، رمزی خواهد نمود.
#    نتیجه مشابه پازل‌های «‎Crypto Quote‎» مشاهده شده در صفحه‌های ‎Op Ed‎ 
#+                                          در روزنامه ‎Sunday‎ است.


key=ETAOINSHRDLUBCFGJMQPVWZYXK
# «‎key‎» چیزی بیشتر از یک الفبای بهم ریخته نیست.
#          تغییر دادن «‎key‎» رمز را تغییر می‌دهد.

#  ساختار ‎cat "$@"‎ ورودی را یا از ‎stdin‎ یا از فایل‌ها دریافت می‌کند.
#اگر از ‎stdin‎ استفاده می‌کنید، ورودی را با یک ‎Control-D‎ خاتمه دهید.
# در غیر اینصورت، نام فایل را به عنوان شناسه خط فرمان مشخص نمایید.

cat "$@" | tr "a-z" "A-Z" | tr "A-Z" "$key"
#        ‎|‎  به حروف بزرگ  ‎|‎    رمزی کردن       
#  روی نقل‌قول‌ها با حروف کوچک، حروف بزرگ، یا حالت مختلط عمل می‌کند.
#            کاراکترهای غیر الفبایی داده شده، بدون تغییر می‌مانند.


#    این اسکریپت را با چیزی مشابه مورد زیر امتحان کنید:
#"Nothing so needs reforming as other people's habits."
# --Mark Twain
#
#                                    خروجی عبارت است از:
# "CFPHRCS QF CIIOQ MINFMBRCS EQ FPHIM GIFGUI'Q HETRPQ."
# --BEML PZERC

#                                       برای شکستن رمز:
# cat "$@" | tr "$key" "A-Z"


# این رمز ساده لوحانه می‌تواند توسط یک نوجوان ‎12‎ ساله فقط
#+                  با استفاده از مداد و کاغذ شکسته شود.

exit 0

#                           :تمرین
#  -----------------------------------------------------
#     اسکریپت را برای انجام رمزنگاری یا رمزگشایی بر اساس
#+                     شناسه(های) خط فرمان، ویرایش کنید.

البته، tr برای مبهم نمودن کد مفید است.

#!/bin/bash
# jabh.sh

x="wftedskaebjgdBstbdbsmnjgz"
echo $x | tr "a-z" 'oh, turtleneck Phrase Jar!'

#مبتنی بر مبحث ‎"Just another Perl hacker"‎ ویکی‌پدیا.


fold

فیلتری که سطرهای ورودی را به عرض تعیین شده می‌شکند. این فیلتر مخصوصاً با گزینه ‎-s‎ مفید است، که سطرها را از فاصله کلمات می‌شکند (مثال ‎16-26‎ و مثال ‎A-1‎ را ببینید).

fmt

قالب‌دهنده فایل بی‌استعداد، مورد استفاده در یک لوله برای «wrap» سطرهای بلند متن خروجی.

مثال ‎16-26‎. لیست فایل قالب‌بندی شده.

#!/bin/bash

WIDTH=40                    # عرض ‎40‎ برای ستون‌ها

b=`ls /usr/local/bin`       #  تهیه یک لیست فایل

echo $b | fmt -w $WIDTH

#با این کد نیز می‌توانست انجام  بشود:
#    echo $b | fold - -s -w $WIDTH
 
exit 0

همچنین مثال ‎16-5‎ را مشاهده کنید.

tip

یک جایگزین قدرتمند fmt برنامه سودمند ‎Kamil Toman‎ به نام par است، که در ‎http://www.cs.berkeley.edu/~amc/Par/‎ قابل دسترس است.


col

این فیلترِ دارای نام گمراه‌کننده، تعویض سطرهای معکوس را از یک جریان ورودی حذف می‌نماید. همچنین سعی می‌کند فضای سفید را با tabهای معادل تعویض کند. مورد استفاده اصلی col در فیلتر کردن خروجی برخی برنامه‌های ویرایشگر متن، از قبیل groff و tbl است.

column

قالب‌دهنده ستون. این فیلتر، خروجی متن فهرست مانند را از طریق درج tab در محل‌های مناسب، به یک جدول «چاپی شکیل» تبدیل می کند.

مثال ‎16-27‎. به کار بردن column برای قالب‌بندی یک فهرست دایرکتوری

#!/bin/bash
# colms.sh
#               یک بهبود بخشی اندک در مثال صفحه ‎man‎ فرمان ‎column‎.


(printf "PERMISSIONS LINKS OWNER GROUP SIZE MONTH DAY HH:MM PROG-NAME\n" \
; ls -l | sed 1d) | column -t
#         ^^^^^^           ^^

# ‎sed 1d‎ در لوله اولین سطر خروجی را که ‎"total  N"‎ خواهد بود، و در
#+  آن ‎N‎ اندازه کل فایل‌های پیدا شده توسط  ‎"ls -l"‎ است، حذف می‌کند.

#                      گزینه ‎-t‎ با ‎column‎ یک جدول شکیل چاپ می‌کند.

exit 0

colrm

فیلتر پاک کننده ستون. این فیلتر، ستون‌ها (کاراکترها) را از یک فایل حذف می‌کند و فایل را بدون ستون‌های حدفاصل معین شده، در stdout می‌نویسد. ‎colrm 2 4 <filename‎ کاراکترهای ستون دوم، سوم، و چهارم را از هر سطر فایل متن filenameحذف می‌کند.مترجم: توجه شود که این یک فیلتر است. بنابراین فقط در خروجی، نه در فایل.

Caution

اگر فایل شامل tabها یا کاراکترهای غیرقابل چاپ باشد، این ممکن است موجب رفتار پیش‌بینی نشده بشود. در چنین موردی، به کار بردن expand و unexpand در یک لوله مقدم بر colrm را در نظر بگیرید.


nl

فیلتر شماره‌گذاری سطر: ‎nl filename‎ محتوای فایل filename را در stdout لیست می‌کند، اما شماره‌های ترتیبی را در ابتدای هر سطر غیر خالی اضافه می‌کند. اگر filename ذکر نشده باشد، روی stdin عمل می‌کند.

خروجی nl بسیار مشابه ‎cat -b‎ است، چون طبق قرارداد nl سطرهای خالی را شماره‌گذاری نمی‌کند.

مثال ‎16-28‎‏. nl: یک اسکریپت خود شماره‌گذار.

#!/bin/bash
# line-number.sh

#این اسکریپت دوبار خودش را با سطرهای شماره‌گذاری شده‌اش در ‎stdout‎ بازتاب می‌دهد.

echo "     line number = $LINENO" #  ‎nl‎ این سطر را به عنوان سطر شماره ‎4‎ می‌بیند
                                  #    (‎nl‎ سطرهای خالی را شماره‌گذاری نمی‌کند).
                                  # ‎cat -n‎ به درستی آن را سطر شماره ‎6‎ می‌بیند.

nl `basename $0`

echo; echo                        #  اکنون، اجازه بدهید با ‎cat -n‎ امتحان کنیم.

cat -n `basename $0`
#تفاوت در آن است که ‎cat -n‎ سطرهای خالی را شماره‌گذاری می‌کند.
#     توجه داشته باشید که ‎nl -ba‎ نیز همینطور عمل خواهد کرد.

exit 0
#----------------------------------------------------------

pr

فیلتر قالب‌بندی چاپ. این فیلتر فایل‌ها (یا stdout) را به بخش‌های مناسب برای چاپ نسخه کاغذی یا مشاهده روی صفحه نمایش صفحه‌بندی می‌کند. گزینه‌های متنوعی، دستکاری سطر و ستون، اتصال سطرها، تنظیم کناره‌ها، شماره‌گذاری سطرها، افزودن سر صفحه‌ها، الحاق فایل‌ها و موارد بسیار دیگری را میسر می‌کنند. فرمان pr بسیاری از توانایی‌های nl‏، paste‏، fold‏، column‎، و expand را درهم می‌آمیزد.

‎pr -o 5 --width=65 fileZZZ | more‎ یک لیست صفحه‌بندی شده زیبا از fileZZZ با کناره‌های تنظیم شده با ‎5‎ و ‎65‎ در صفحه نمایش ارایه می‌کند.

یک گزینه بویژه سودمند، گزینه ‎-d‎ است، که نگارش یک خط در میان (همانند نتیجه ‎sed -G‎) را تحمیل می‌کند.

gettext

بسته gettext گنو مجموعه‌ای از برنامه‌های سودمند برای بومی‌سازی و ترجمه متن خروجی برنامه‌ها به زبان‌های خارجی است. درحالیکه در آغاز برای برنامه‌های C در نظر گرفته شد، اکنون تعدادی از زبان‌های برنامه‌نویسی و اسکریپت‌نویسی را به طور کامل پشتیبانی می‌کند.

برنامه gettext روی اسکرپت‌های پوسته عمل می‌کند. صفحه info را مشاهده کنید.

msgfmt

برنامه‌ای برای تولید فهرست‌ مشخصات پیغام‌‌های باینری. برای محلی‌کردن مورد استفاده است.

iconv

برنامه سودمندی برای تبدیل فایل(ها) به یک encoding (مجموعه کاراکتر) متفاوت. استفاده اصلی آن در محلی‌سازی است.

#تبدیل یک رشته از ‎UTF-8‎ به ‎UTF-16‎ و چاپ در BookList
function write_utf8_string {
    STRING=$1
    BOOKLIST=$2
    echo -n "$STRING" | iconv -f UTF8 -t UTF16 | \
    cut -b 3- | tr -d \\n >> "$BOOKLIST"
}

#   از اسکریپت ‎"booklistgen.sh"‎ نوشته ‎Peter Knowle‎
#+ برای تبدیل فایل‌ها به قالب ‎Sony Librie/PRS-50X‎.
#  (http://booklistgensh.peterknowles.com)

recode

این را به عنوان یک نگارشِ تفننی‌تر iconv فوق در نظر بگیرید. این برنامه سودمندِ بسیار فراگیرنده‌ای برای تبدیل فایل به یک طرح encoding متفاوت است. توجه داشته باشید که recode بخشی از استاندارد نصب لینوکس نیست.

TeX‏، gs

TeX و Postscript زبان‌های نشانه‌گذاری متن هستند که برای آماده‌سازی نسخه جهت چاپ یا نمایش تصویری قالب‌بندی شده استفاده می‌شوند.

TeX سیستم حروف‌چینی استادانه ‎Donald Knuth‎ است. بیشتر اوقات نوشتن یک اسکریپت پوسته کپسول کننده تمام گزینه‌ها و شناسه‌های داده شده به یکی از این زبان‌های نشانه‌گذاری، مناسب است.

Ghostscript ‏(gs) مفسر Postscript گنو است.

texexec

برنامه سودمندی برای پردازش فایل‌های TeX و pdf. در اکثر توزیع‌های لینوکس در ‎/usr/bin‎ قرار دارد، در واقع یک روکش ( wrapper) پوسته است که Perl را برای فراخوانی نمودن Tex احضار می‌کند.

texexec --pdfarrange --result=Concatenated.pdf *pdf

#         تمام فایل‌های pdf در دایرکتوری کاری جاری را در یک فایل به‌هم پیوسته
#+                      با نام ‎Concatenated.pdf‎ با یکدیگر ادغام می‌کند. . .
#              ( گزینه ‎--pdfarrange‎ یک فایل ‎pdf‎ را دوباره صفحه‌بندی می‌کند.)
#+                                       گزینه ‎--pdfcombine‎ را نیز ببینید.
# سطر فرمان فوق می‌تواند پارامتر دار شده  و در یک اسکریپت پوسته قرار بگیرد. 

enscript

برنامه سودمندی برای تبدیل فایل‌های متن ساده به PostScript

برای مثال، ‎enscript filename.txt -p filename.ps‎ فایل خروجی ‎PostScript‎ به نام filename.ps را تولید می‌کند.

groff‏، tbl‏، eqn

یک زبان دیگر نمایش شکیل و علامت‌گذاری شده متن، groff است. این یک نگارش ارتقاء یافته گنو از بسته حروف‌چینی و نمایش ‎roff/troff‎ یونیکس ارجمند است. صفحه‌های Man از groff استفاده می‌کنند.

برنامه سودمند پردازش جدول tbl بخش پر اهمیتی از groff است، که عملکرد آن تبدیل جدول نشانه‌دار به فرمان‌های groff است.

برنامه سودمند پردازش معادله eqn نیز بخشی از groff است، و کارآیی آن در تبدیل معادله نشانه‌دار به فرمان‌های groff است.

مثال ‎16-29‎‏. manview: نمایش صفحه‌های man قالب‌دار

#!/bin/bash
# ‎manview.sh:‎ .را برای نمایش قالب‌بندی می‌کند ‎man‎ منبع یک صفحه‌

#           این اسکریپت موقع نوشتن source صفحه man مفید است.
#  به شما اجازه می‌دهد در حالیکه روی صفحه کار می‌کنید، نتایج را
#+                                  به طور درجا مشاهده کنید.

E_WRONGARGS=85

if [ -z "$1" ]
then
  echo "Usage: `basename $0` filename"
  exit $E_WRONGARGS
fi

# ---------------------------
groff -Tascii -man $1 | less
#از صفحه ‎man‎ برای ‎groff‎.
# ---------------------------

#اگر صفحه ‎man‎ شامل جدول‌ها و/یا معادله‌ها باشد،
#+                  آنوقت کد فوق، بالا می‌آورد.
#سطر زیر می‌تواند چنین مواردی را مدیریت نماید.
#
# gtbl < "$1" | geqn -Tlatin1 | groff -Tlatin1 -mtty-char -man
#
#با تشکر از ‎S.C.‎

exit $?   # اسکریپت ‎maned.sh‎ را نیز ملاحظه نمایید.

همچنین مثال ‎A-39‎ را مشاهده کنید.

lex‏، yacc

تحلیل‌کننده واژه‌‌ای ‌lex‏ برنامه‌هایی برای انطباق الگو ارایه می‌کند. این تحلیل‌کننده در سیستم‌های لینوکس با flex انحصاری نشده، تعویض گردیده است.

برنامه سودمند yacc یک تجزیه‌کننده مبتنی بر مجموعه‌ای از مشخصات تولید می‌کند. این برنامه نیز در سیستم‌های لینوکس با bison غیر انحصاری، تعویض گردیده است.

یادداشت‌ها

[1]

این فقط برای نگارش گنوی tr صحیح است، نه برای نگارش عمومی که اغلب روی سیستم‌های یونیکس تجارتی یافت می‌شود.