فصل هشتم - جانشینی‌ها

از Linuxreview Wiki
پرش به: ناوبری, جستجو


در فصل قبل چگونگی دستیابی به یک متغیر با استفاده از کاراکتر $ شرح داده شد. عملیات بازیابی مقدار یک کاراکتر عملیات جانشینی متغیر یا variable substitution نامیده میشود. در این فصل چهار جانشینی زیر بررسی میشوند:



محتویات

[نهفتن]

جانشینی در نام فایل‌ها(globbing)

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

جدول الگو که میتوان با استفاده از آن‌ها از جانشینی نام‌فایل استفاده کرد به شرح زیر است:
* : وقوع صفر یا بیشتر از صفر کاراکتر از هر نوعی
? : وقوع یک کاراکتر از هر نوعی
[characters] : وقوع یک کاراکتر از لیست کاراکترهای مشخص شده در charachters


نکته: میتوان در هر دستوری که در آن از نام یک فایل استفاده میشود، از جانشینی نام‌فایل استفاده کرد.



استفاده از *

ساده‌ترین راه برای جانشینی نام‌فایل استفاده از * به تنهایی است. کاراکتر * به این معنی است که، شل میتواند صفر یا بیشتر از صفر تکرار از هر کاراکتری را جایگزین کند. به عبارت دیگر فایل با هر نامی را جانشین * کند.
مثال:

$ls -a *

این دستور تمامی فایل‌ها و محتوای تمام دایرکتوری‌ها و زیر دایرکتوری‌ها در مسیر جاری را نمایش میدهد.
در بسیار موارد استفاده از * به تنهایی میتواند مفید باشد، ولی قدرت استفاده از آن در ترکیب با عبارات به صورت پیشوند، پسوند یا میانوند است که هر کدام در ادامه بررسی میشوند.


استفاده از * در پایان عبارات

شکل کلی استفاده از * در عبارات به صورت پسوندی به صورت زیر است:

command prefix*

که در آن command نام دستور و prefix عباراتی است که نام‌فایل با آن آغاز میشود.

مثال:

$ ls ch1*

این دستور نام تمام فایل‌ها و دایرکتوری‌هایی که با عبارت ch1 آغاز میشوند را نشان میدهد که خروجی این دستور میتواند به شکل زیر باشد:

ch10-01 ch10-02 ch10-03 ch11-01 ch11-02 ch11-03

استفاده از * در آغاز عبارات

شکل کلی استفاده از * در عبارات به صورت پسوندی به صورت زیر است:

command *suffix

که در آن command نام دستور و suffix عباراتی است که نام‌فایل با آن پایان میابد.

مثال:

$ ls *doc

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

ch10-01.doc ch10-02.doc ch10-03.doc
ch10-04.doc ch10-05.doc ch10-06.doc
ch10-07.doc ch10-06.doc ch10-17.doc

استفاده از * در عبارات به صورت میانوند

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

command prefix*suffix

که نشان دهنده‌ی تمامی عباراتی است که با عبارت prefix شروع شده و با suffix اتمام می‌یابند.

مثال:

$ ls Backup*doc
Backup of ch10-01.doc Backup of ch10-02.doc Backup of ch10-03.doc
Backup of ch10-04.doc Backup of ch10-05.doc Backup of ch10-06.doc


همچنین امکان استفاده از چندین * در بین عبارات نیز وجود دارد.
مثال:

$ ls CGI*st*java
CGIPost.java CGITester.java CGITest.java

استفاده از ?

استفاده از کاراکتر ? به این معنی است که، شل میتواند یک کاراکتر از هر نوعی را جایگزین کند.
کاراکتر ? نیز همانند کاراکتر * میتواند به صورت پیشوند، پسوند یا میانوندی مورد استفاده قرار بگیرد.
مثال:

$ ls ch0*.doc

که میتواند خروجی به شکل زیر داشته تولید کند:

ch01-1.doc ch01.doc ch05.doc ch06-2.doc
ch01-2.doc ch02-1.doc ch050.doc ch06.doc
ch01.doc ch02-2.doc ch06-1.doc ch060.doc
ch02.doc ch03-2.doc ch04-1.doc ch040.doc
ch020.doc ch03.doc ch04-2.doc ch05-1.doc
ch03-1.doc ch030.doc ch4.doc ch5.doc

در این مثال فایل با نام ch0.doc، حتی اگر وجود داشته باشد هم نمایش داده نمیشود.
میتوان از چندین ? به صورت پشت سر هم یا جداگانه در عبارات استفاده کرد. مثال:

$ ls ch??.doc
ch01-1.doc ch010.doc ch05.doc ch06-2.doc
ch01-2.doc ch02-1.doc ch050.doc ch06.doc
ch01.doc ch02-2.doc ch06-1.doc ch060.doc
ch02.doc ch03-2.doc ch04-1.doc ch040.doc
ch020.doc ch03.doc ch04-2.doc ch05-1.doc
ch03-1.doc ch030.doc

استفاده از الگو به شکل [characters]

دو مشکل عمده‌ی استفاده از کاراکترهای ؟ و * به شرح زیر است:

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

برای حل مشکلات بالا میتوان از الگوی [characters] به صورت زیر استفاده کرد:

$command prefix[characters]suffix

که در این حالت characters ، کاراکترهایی است که شما برای جانشینی میتوانید استفاده کنید.
مثال:

$ ls ch0[0123456789].doc
ch01.doc ch02.doc ch03.doc
ch04.doc ch05.doc ch06.doc

که در آن نام‌فایل میتواند با یکی از اعداد ۰ تا ۹ جانشین شود.

نکته: به جای نوشتن کل کاراکترهای مورد نظر میتوان محدوده‌ی آنها را با استفاده از (-) مشخص کرد.


مثال:دو عبارت زیر با هم برابرند:

$ ls ch0[0123456789].doc
$ ls ch0[0-9].doc

همچنین ادغام چند محدوده یا ادغام این شکل از جانشینی با، با کاراکترهای * و ? امکان پذیر است.

مثال‌ها:

$ ls [a-z]*

نمایش تمام فایل‌هایی که با یک حرف کوچک شروع میشوند

$ ls [A-Z]*

نمایش تمام فایل‌هایی که با یک حرف بزرگ شروع میشوند

$ ls [a-zA-Z]*

نمایش تمام فایل‌هایی که با یک حرف شروع میشوند

$ ls *[a-zA-Z0-9]

نمایش تمام فایل‌هایی که با یکی از اعداد یا حروف پایان مییابند


لغو جانشین شدن یک الگو با استفاده از !

برای جلوگیری در جانیشنی نام‌فایل‌ها میتوان از کاراکتر ! به صورت زیر استفاده کرد:

command [!characters]

در این حالت کاراکترهایی که در داخل [] اعلان شده‌اند جانشین نمیشوند.
مثال:
دو عبارت زیر با هم معادل هستند

$ ls [b-zA-Z0-9\-_\+\=\\\'\"\{\[\}\]
$ ls [!a]*

این حالت زمانی مفید خواهد بود که شما بخواهید از جانشینی یک یا چند کاراکتر خاص جلوگیری کنید


نکته: جانشینی الگوها در نام فایل‌ها، توسط خود شل انجام می‌شود، نه توسط دستور. به عنوان مثال، اگر در دایرکتوری جاری، فایل‌هایی که اسمشان با حرف a شروع می‌شود، سه فایل a1 و a2 و a3 باشند، در اینصورت دستور

$ ls a*

مثل دستور

$ ls a1 a2 a3

می‌ماند، در واقع دستور ls متوجه نمی‌شود که شما از الگوی جانشینی بوسیلهٔ * استفاده کرده‌اید و فقط سه آرگومان دریافت می‌کند


نکته: اگر خود اسم/مسیر فایل شامل علامت‌هایی مثل * یا ? باشد، باید اسم فایل/مسیر فایل را داخل نقل یگانه یا دوگانه بگذارید (نقل یگانه مطمئن‌تر است). به این موضوع در فصل بعد پرداخته شده است.


جانشینی در پارامترها

استفاده از مقادیر پیش‌فرض

شکل کلی این حالت به صورت زیر است:

${parameter:-defaultValue}
var=${parameter:-defaultValue}

اگر parameter مقدار دهی نشده باشد از defualtvalue استفاده می‌شود

مثال:

u=${1:-root}

در اینجا در صورتی که متغیر $1 مقدار دهی نشده باشد از متغیر root برای مقدار دهی u استفاده می‌شود

مثال:
اسکریپت زیر را در نظر بگیرید:

_jail_dir="${1:-/home/phpcgi}"
echo "Setting php-cgi at ${_baroon_dir}..."

حالا این اسکریپت را به صورت‌های زیر اجرا کنید و خروجی آن را بررسی کنید:

./script.sh /baroon
./script.sh /home/httpd/baroon
./script.sh


قرار دادن مقدار پیش فرض

شکل کلی این وضعیت به صورت زیر است:

${var:=value}
var=${USER:=value}

در اینجا عمل انتصاب زمانی انجام می‌شود که متغیر USER دارای هیچ مقداری نباشد. به عبارتی در صورتی که متغیر USER دارای مقدار باشد عمل انتصاب انجام نمی‌شود.

مثال
اسکریپت زیر را در نظر بگیرید:

echo $USER
echo ${USER:=foo}
unset USER
echo ${USER:=foo}

خروجی این اسکریپت به شکل زیر است:

baroon
baroon
foo

جانشینی در دستورات

در جانشینی دستورات شما قادر خواهید بود تا از خروجی یک دستور در یک دستور دیگر استفاده کنید.
شکل کلی استفاده از جانشینی در دستورات به صورت زیر است:

`command`

که در اینجا command میتواند هر کدام از دستورات شل باشد

توجه: مطمئن باشید که از کاراکتر `` استفاده میکنید. خطای رایج استفاده از ' (quote) به جای ` (back quote) است. برای تایپ این کاراکتر از دکمه‌ای که بالای Tab قرار دارد استفاده کنید.


مثال:

DATE=`date`

خروجی دستور date در متغیر DATE ذخیره میشود

USERS=`who | wc -l `

تعداد کاربران در متغیر USERS ذخیره میشود

UP=`date ; uptime`

خروجی دو دستور date و uptime در متغیر UP ذخیره میشود

جانشینی در عبارات محاسباتی

در bash امکان استفاده از عبارات محاسباتی برای اعداد صحیح بدون استفاده از برنامه‌هایی نظیر expr فراهم شده است.
شکل کلی استفاده از عبارات محاسباتی صحیح به صورت زیر است:

[expression]

و یا

((expression))


که در آن expression یک عبارت ریاضی مجاز به استفاده از عملگرهای / + - * و پرانتز () میباشد.
مثال:

foo=$[ ((5 + 3*2) - 4) / 2 ]

یا

foo=$(( ((5 + 3*2) - 4) / 2 ))

که در این مثال مقدار متغیر foo برابر ۳ میشود.

نکته: همانطور که اشاره شد از این جانشینی فقط برای اعداد صحیح میتوان استفاده کرد و حاصل همیشه باید یک عدد صحیح باشد، در نتیجه در مثال بالا متغیر foo‌ به جای ۳.۵ ، مقدار ۳ را میپذیرد.






Eman ‏۱۵ فوریهٔ ۲۰۱۲، ساعت ۱۱:۵۱ (UTC)

ابزارهای شخصی
گویش‌ها
فضاهای نام
عملکردها
گشتن
کتاب‌ها
مقاله‌ها
جعبه‌ابزار