| ZSHEXPN(1) | General Commands Manual | ZSHEXPN(1) |
نام (NAME)
zshexpn - گسترش و جایگزینی در zsh
توضیحات (DESCRIPTION)
انواع گسترشهای زیر به ترتیب مشخصشده در پنج مرحله انجام میشوند:
- گسترش تاریخچه (History Expansion)
- این مورد تنها در شلهای تعاملی انجام میشود.
- گسترش نام مستعار (Alias Expansion)
- نامهای مستعار بلافاصله پیش از تجزیه خط فرمان، همانطور که ذیل Aliasing در zshmisc(1) توضیح داده شده است، گسترش مییابند.
- جایگزینی فرایند (Process Substitution)
- گسترش پارامتر (Parameter Expansion)
- جایگزینی دستور (Command Substitution)
- گسترش محاسباتی (Arithmetic Expansion)
- گسترش آکولاد (Brace Expansion)
- این پنج مورد به شیوه چپ-به-راست انجام میشوند. روی هر آرگومان، هر یک از این پنج مرحله که مورد نیاز باشد، یکی پس از دیگری اعمال میگردد. بنابراین، به عنوان مثال، تمامی بخشهای گسترش پارامتر پیش از آغاز جایگزینی دستور به پایان میرسند. پس از این گسترشها، تمامی رخدادهای نقلقولنشده از نویسههای `\'، `'' و `"' حذف میشوند.
- گسترش نام فایل (Filename Expansion)
- اگر گزینه SH_FILE_EXPANSION تنظیم شده باشد، ترتیب گسترش به منظور سازگاری با sh و ksh تغییر مییابد. در این حالت گسترش نام فایل بلافاصله پس از گسترش نام مستعار و پیش از مجموعه گسترشهای پنجگانه مذکور انجام میشود.
- تولید نام فایل (Filename Generation)
- این گسترش، که معمولاً با عنوان globbing شناخته میشود، همیشه در آخرین مرحله انجام میگیرد.
بخشهای زیر انواع گسترش را با جزئیات شرح میدهند.
گسترش تاریخچه (HISTORY EXPANSION)
گسترش تاریخچه به شما امکان میدهد از کلمات خطوط فرمان پیشین در خط فرمانی که در حال وارد کردن آن هستید استفاده کنید. این کار اصلاح املایی و تکرار دستورها یا آرگومانهای پیچیده را ساده میسازد.
بلافاصله پیش از اجرا، هر دستور در فهرست تاریخچه ذخیره میشود که اندازه آن توسط پارامتر HISTSIZE کنترل میگردد. در هر صورت، جدیدترین دستور همیشه نگهداری میشود. هر دستور ذخیرهشده در فهرست تاریخچه یک رویداد (event) تاریخچه نامیده میشود و شمارهای به آن اختصاص مییابد که با شروع به کار شل از ۱ (یک) آغاز میگردد. شماره تاریخچهای که ممکن است در اعلان خط فرمان (prompt) خود ببینید (بخش EXPANSION OF PROMPT SEQUENCES در zshmisc(1) را ببینید) شمارهای است که به دستور بعدی اختصاص خواهد یافت.
نمای کلی (Overview)
یک گسترش تاریخچه با نخستین نویسه از پارامتر histchars آغاز میشود که بهطور پیشفرض `!' است، و ممکن است در هر کجای خط فرمان رخ دهد، از جمله درون نقلقول دوتایی (اما نه درون نقلقول تکی '...' یا نقلقولهای سبک سی $'...'، و نه هنگامی که با یک بکاسلش گریز داده شده باشد).
به دنبال این نخستین نویسه، یک تعیینکننده رویداد اختیاری (بخش `Event Designators' را ببینید) و سپس یک تعیینکننده کلمه اختیاری (بخش `Word Designators' را ببینید) قرار میگیرد؛ اگر هیچیک از این تعیینکنندهها وجود نداشته باشند، هیچ گسترش تاریخچهای رخ نمیدهد.
خطوط ورودی حاوی گسترشهای تاریخچه، پس از گسترش یافتن بازتاب (echo) داده میشوند، اما این کار پیش از اعمال هرگونه گسترش دیگر و قبل از اجرای دستور رخ میدهد. همین شکل گسترشیافته است که برای مراجعات بعدی به عنوان رویداد تاریخچه ثبت میشود.
گسترشهای تاریخچه تودرتو نمیشوند.
بهطور پیشفرض، یک ارجاع تاریخچه بدون تعیینکننده رویداد، به همان رویدادی ارجاع میدهد که ارجاع تاریخچه پیشین در همان خط فرمان به آن اشاره کرده است؛ اگر تنها ارجاع تاریخچه در یک دستور باشد، به دستور قبلی اشاره میکند. با این حال، اگر گزینه CSH_JUNKIE_HISTORY فعال باشد، آنگاه هر ارجاع تاریخچه بدون مشخصکننده رویداد همیشه به دستور قبلی ارجاع میدهد.
برای نمونه، `!' تعیینکننده رویداد برای دستور قبلی است، بنابراین `!!:1' همیشه به کلمه نخست دستور قبلی اشاره دارد و `!!$' همیشه به آخرین کلمه دستور قبلی ارجاع میدهد. با فعال بودن CSH_JUNKIE_HISTORY، آنگاه `!:1' و `!$' دقیقاً به همان شیوه `!!:1' و `!!$' عمل میکنند. در مقابل، اگر CSH_JUNKIE_HISTORY غیرفعال باشد، `!:1' و `!$' به ترتیب به کلمات نخست و آخر همان رویدادی اشاره میکنند که نزدیکترین ارجاع تاریخچه پیشین در خط فرمان فعلی به آن اشاره کرده است، یا در صورتی که هیچ ارجاع پیشینی وجود نداشته باشد، به دستور قبلی ارجاع خواهند داد.
توالی نویسههای `^foo^bar' (که در آن `^' در واقع دومین نویسه از پارامتر histchars است) دستور قبلی را تکرار میکند و رشته bar را جایگزین رشته foo میسازد. دقیقتر آنکه، توالی `^foo^bar^' مترادف با `!!:s^foo^bar^' است؛ بنابراین سایر اصلاحکنندهها (بخش `Modifiers' را ببینید) میتوانند پس از آخرین `^' قرار گیرند. بهویژه، `^foo^bar^:G' یک جایگزینی سراسری را انجام میدهد.
اگر شل در ورودی با توالی نویسههای `!"' مواجه شود، سازوکار تاریخچه موقتاً تا زمانی که لیست فعلی (به zshmisc(1) مراجعه کنید) بهطور کامل تجزیه شود، غیرفعال میگردد. توالی `!"' از ورودی حذف میشود و نویسههای `!' پس از آن دیگر هیچ اهمیت ویژهای نخواهند داشت.
شکلی با راحتی کمتر اما قابلفهمتر از پشتیبانی تاریخچه دستورها توسط دستور توکار fc ارائه شده است..SS "تعیینکنندههای رویداد (Event Designators)" یک تعیینکنندهٔ رویداد، ارجاعی به یک مدخل خط فرمان در فهرست تاریخچه (history) است. در فهرست زیر، به یاد داشته باشید که `!' ابتدایی در هر مورد میتواند با تنظیم پارامتر histchars به نویسهٔ دیگری تغییر یابد.
- !
- شروع یک بسط تاریخچه، مگر آنکه پس از آن یک نویسهٔ فاصله، خط جدید، `=' یا `(' بیاید. اگر بلافاصله پس از آن یک تعیینکنندهٔ کلمه بیاید (بخش `تعیینکنندههای کلمه` را ببینید)، این کار یک ارجاع تاریخچه بدون تعیینکنندهٔ رویداد تشکیل میدهد (بخش `نمای کلی` را ببینید).
- !!
- ارجاع به دستور قبلی. به تنهایی، این بسط دستور قبلی را تکرار میکند.
- !n
- ارجاع به خط فرمان n.
- !-n
- ارجاع به خط فرمان فعلی منهای n.
- !str
- ارجاع به تازهترین دستوری که با str شروع میشود.
- !?str[?]
- ارجاع به تازهترین دستوری که شامل str است. نویسهٔ `?' پایانی در صورتی لازم است که قرار باشد پس از این ارجاع یک اصلاحکننده بیاید یا هر متنی دنبال آن باشد که نباید بخشی از str در نظر گرفته شود.
- !#
- ارجاع به خط فرمان فعلی که تا اینجا تایپ شده است. با این خط طوری رفتار میشود که گویی تا کلمهٔ قبل از ارجاع `!#' (شامل خود آن کلمه) کامل شده است.
- !{...}
- جداسازی ارجاع تاریخچه از نویسههای مجاور (در صورت لزوم).
تعیینکنندههای کلمه (Word Designators)
یک تعیینکنندهٔ کلمه مشخص میکند که کدام کلمه یا کلمات از یک خط فرمان دادهشده باید در ارجاع تاریخچه گنجانده شوند. معمولاً یک `:' مشخصات رویداد را از تعیینکنندهٔ کلمه جدا میکند. تنها در صورتی میتوان آن را حذف کرد که تعیینکنندهٔ کلمه با یکی از نویسههای `^'، `$'، `*'، `-' یا `%' شروع شود. تعیینکنندههای کلمه عبارتند از:
- 0
- نخستین کلمهٔ ورودی (دستور).
- n
- آرگومان nام.
- ^
- نخستین آرگومان؛ یعنی 1.
- $
- آخرین آرگومان.
- %
- کلمهای که با جستجوی (تازهترین) ?str مطابقت دارد.
- x-y
- محدودهای از کلمات؛ مقدار پیشفرض x برابر 0 است.
- *
- تمام آرگومانها، یا یک مقدار تهی در صورتی که هیچ آرگومانی وجود نداشته باشد.
- x*
- کوتاهشدهٔ `x-$'.
- x-
- مانند `x*' اما با حذف کلمهٔ $.
توجه داشته باشید که تعیینکنندهٔ کلمهٔ `%' تنها هنگامی کار میکند که در یکی از حالتهای `!%'، `!:%' یا `!?str?:%' استفاده شود، و فقط زمانی که پس از یک بسط !? (احتمالاً در یک دستور پیشتر) به کار رود. هر حالت دیگری منجر به خطا خواهد شد، گرچه ممکن است این خطا چندان واضح و آشکار نباشد..SS "تغییردهندهها (Modifiers)" پس از مشخصکنندهٔ اختیاری واژه (word designator)، میتوانید دنبالهای از یک یا چند تغییردهندهٔ زیر را اضافه کنید که پیش از هر یک از آنها یک «:» قرار میگیرد. این تغییردهندهها، بهجز مواردی که ذکر شده، روی نتیجهٔ تولید نام فایل (filename generation) و بسط متغیر (parameter expansion) نیز کار میکنند.
- a
- تبدیل یک نام فایل به مسیر مطلق: در صورت نیاز، دایرکتوری جاری را به ابتدای آن میافزاید؛ بخشهای «.» مسیر را حذف میکند؛ و بخشهای «..» مسیر و بخشهایی را که بلافاصله پیش از آنها آمدهاند حذف میکند.
این تبدیل بدون توجه به محتویات سیستمفایل انجام میشود، یعنی بر روی دایرکتوری منطقی عمل میکند و نه فیزیکی. این تبدیل به همان شیوهای رخ میدهد که تغییر دایرکتوری در حالتی که هیچیک از گزینههای CHASE_DOTS یا CHASE_LINKS تنظیم نشده باشند انجام میگیرد. برای نمونه، «/before/here/../after» همیشه به «/before/after» تبدیل میشود، صرفنظر از اینکه «/before/here» وجود داشته باشد یا اینکه چه نوع شیئی (دایرکتوری، فایل، پیوند نمادین، وغیره) باشد.
- A
- تبدیل نام فایل به یک مسیر مطلق، همانند تغییردهندهٔ «a»، و سپس ارسال نتیجه به تابع کتابخانهای realpath(3) برای حل پیوندهای نمادین.
نکته: در سیستمهایی که فاقد تابع کتابخانهای realpath(3) هستند، پیوندهای نمادین حل نمیشوند، بنابراین در آن سیستمها «a» و «A» معادل یکدیگرند.
نکته: foo:A و realpath(foo) در برخی ورودیها متفاوت عمل میکنند. برای معادل معنایی دقیق realpath(foo)، تغییردهندهٔ «P» را ببینید.
- c
- تبدیل نام یک دستور به یک مسیر مطلق از طریق جستجو در مسیر دستور مشخصشده توسط متغیر PATH. این قابلیت برای دستورهایی که شامل بخشهای دایرکتوری هستند کار نمیکند. همچنین توجه داشته باشید که این ویژگی معمولاً بهعنوان یک تحدیدکنندهٔ glob کار نمیکند مگر آنکه فایلی با همان نام در دایرکتوری جاری یافت شود.
- e
- حذف همهٔ بخشها بهجز پسوند نام فایل پس از «.»؛ تعریف پسوند نام فایل را در توضیحات تغییردهندهٔ r در زیر ببینید. توجه داشته باشید که طبق آن تعریف، اگر رشته با «.» پایان یابد، نتیجه خالی خواهد بود.
- h [ digits ]
- حذف آخرین بخش از نام مسیر، و کوتاه کردن مسیر به اندازهٔ یک سطح دایرکتوری: این بخش «سر» (head) نام مسیر است. عملکرد آن مشابه «dirname» است. اگر بلافاصله پس از h (بدون فاصله یا جداکنندهٔ دیگر) ارقام دهدهی بیاید، و مقدار عدد حاصل غیرصفر باشد، بهجای حذف بخش انتهایی، آن تعداد از بخشهای ابتدایی نگه داشته میشوند. در یک مسیر مطلق، «/» ابتدایی نخستین بخش به شمار میرود، بنابراین برای نمونه اگر var=/my/path/to/something باشد، آنگاه ${var:h3} با /my/path جایگزین میشود. علامتهای «/» متوالی همانند یک «/» تک رفتار میشوند. در جایگزینی متغیر، ارقام تنها در صورتی قابل استفادهاند که عبارت درون آکولاد باشد؛ برای نمونه جایگزینی به فرم کوتاه $var:h2 بهصورت ${var:h}2 رفتار میشود، نه بهصورت ${var:h2}. هیچ محدودیتی برای استفاده از ارقام در جایگزینی تاریخچه یا تحدیدکنندههای globbing اعمال نمیشود. اگر تعداد بخشهای درخواستی بیشتر از بخشهای موجود باشد، کل مسیر جایگزین میشود (بنابراین خطای «failed modifier» در بسط تاریخچه رخ نمیدهد).
- l
- تبدیل همهٔ واژهها به حروف کوچک.
- p
- چاپ دستور جدید بدون اجرای آن. تنها در بسط تاریخچه (history expansion) کار میکند.
- P
- تبدیل نام فایل به یک مسیر مطلق، همانند realpath(3). مسیر حاصل مطلق خواهد بود، به همان مدخل دایرکتوریِ نام فایل ورودی اشاره خواهد کرد، و هیچیک از بخشهای آن پیوند نمادین یا برابر با «.» یا «..» نخواهند بود.
برخلاف realpath(3)، بخشهای انتهاییِ ناموجود مجاز هستند و حفظ میشوند.
- q
- نقلقول کردن (quote) کلمات جایگزینشده، برای جلوگیری از بسطهای بیشتر. در بسط تاریخچه و بسط متغیر کار میکند، هرچند برای متغیرها تنها در صورتی مفید است که متن حاصل قرار باشد مجدداً ارزیابی شود، مثلاً توسط eval.
- Q
- حذف یک سطح از نقلقولها از کلمات جایگزینشده.
- r
- حذف پسوند نام فایل و باقی گذاشتن نام ریشه (root name). رشتههای بدون پسوند نام فایل دستنخورده باقی میمانند. پسوند نام فایل یک «.» است که به دنبال آن هر تعداد نویسه (از جمله صفر) بیاید که نه «.» باشند و نه «/» و تا انتهای رشته ادامه داشته باشند. برای نمونه، پسوند «foo.orig.c» برابر با «.c» است، و «dir.c/foo» هیچ پسوندی ندارد.
- s/l/r[/]
- جایگزین کردن r بهجای l همانگونه که در زیر شرح داده شده است. جایگزینی تنها برای اولین رشتهای که با l مطابقت دارد انجام میشود. برای آرایهها و تولید نام فایل، این عمل بر روی هر واژه از متن بسطیافته اعمال میگردد. برای نکات بیشتر دربارهٔ جایگزینیها، به ادامه مراجعه کنید.
شکلهای «gs/l/r» و «s/l/r/:G» جایگزینی سراسری را انجام میدهند، یعنی تمام وقوعهای l را با r جایگزین میکنند. توجه داشته باشید که g یا :G باید دقیقاً در همان موقعیت نشاندادهشده قرار گیرند.
نکات بیشتر دربارهٔ این نوع جایگزینی را در زیر ببینید.
- &
- تکرار جایگزینی قبلی s. همانند s، میتواند بلافاصله پس از یک g بیاید. در بسط متغیر، & باید درون آکولاد قرار گیرد، و در تولید نام فایل باید با یک بکاسلش نقلقول (quote) شود.
- t [ digits ]
- حذف تمام بخشهای ابتدایی مسیر و باقی گذاشتن بخش پایانی (دنباله یا tail). عملکرد آن مشابه «basename» است. ابتدا هرگونه اسلش انتهایی حذف میشود. ارقام دهدهی همانطور که در بالا برای (h) توضیح داده شد مدیریت میشوند، اما در اینجا بهجای مقدار پیشفرض ۱، آن تعداد از بخشهای انتهایی نگهداشته میشوند؛ با ۰ نیز مانند ۱ رفتار میشود.
- u
- تبدیل همهٔ واژهها به حروف بزرگ.
- x
- مشابه q، اما شکستن به واژهها در فاصلههای خالی (whitespace). با بسط متغیر کار نمیکند.
جایگزینی s/l/r/ به این صورت کار میکند. بهطور پیشفرض، سمت چپ جایگزینیها الگو نبوده، بلکه رشتههای نویسهای هستند. هر نویسهای میتواند بهجای «/» بهعنوان جداکننده استفاده شود. یک بکاسلش نویسهٔ جداکننده را نقلقول میکند. نویسهٔ «&» در سمت راست r، با متن سمت چپ l جایگزین میشود. نویسهٔ «&» را میتوان با یک بکاسلش نقلقول کرد. یک l تهی، رشتهٔ پیشین را یا از l قبلی و یا از رشتهٔ پویش زمینهای s از «!?s» به کار میگیرد. اگر بلافاصله پس از r نویسهٔ خط جدید بیاید، میتوانید راستترین جداکننده را حذف کنید؛ راستترین «?» در یک پویش زمینه نیز به طور مشابه میتواند حذف شود. توجه داشته باشید که رکورد مشترکی از آخرین l و r در تمامی انواع بسط نگهداری میشود.
توجه داشته باشید که اگر «&» در داخل تحدیدکنندههای glob استفاده شود، به یک بکاسلش اضافی نیاز است زیرا در این حالت & یک نویسهٔ خاص محسوب میشود.
همچنین توجه داشته باشید که ترتیب بسطها بر تفسیر l و r تأثیر میگذارد. هنگام استفاده در بسط تاریخچه، که پیش از هر بسط دیگری رخ میدهد، با l و r مانند رشتههای تحتاللفظی رفتار میشود (بهجز مواردی که در توضیح HIST_SUBST_PATTERN در زیر آمده است). هنگام استفاده در بسط متغیر، ابتدا جایگزینی r در مقدار متغیر انجام میشود، و سپس هرگونه ارجاع اضافی به فرآیند، متغیر، دستور، محاسبات عددی، یا آکولاد اعمال میگردد؛ این امر ممکن است در صورتی که l بیش از یک بار در مقدار اولیه ظاهر شود، آن جایگزینیها و بسطها را بیش از یک بار ارزیابی کند. هنگام استفاده در یک تحدیدکنندهٔ glob، هرگونه جایگزینی یا بسط یکبار در زمان تجزیهٔ تحدیدکننده انجام میشود، حتی پیش از آنکه عبارت «:s» به بخشهای l و r تقسیم شود.
اگر گزینهٔ HIST_SUBST_PATTERN تنظیم شده باشد، با l بهصورت یک الگو به شکل معمولِ توضیحدادهشده در بخش FILENAME GENERATION در زیر رفتار میشود. این قابلیت در تمام جاهایی که تغییردهندهها در دسترس هستند قابل استفاده است؛ با این حال، توجه داشته باشید که در تحدیدکنندههای globbing، جایگزینی متغیر از قبل انجام گرفته است، بنابراین متغیرها در رشتهٔ جایگزین باید نقلقول (quote) شوند تا اطمینان حاصل شود که در زمان مناسب جایگزین میشوند. همچنین توجه داشته باشید که الگوهای پیچیدهٔ مورد استفاده در تحدیدکنندههای globbing ممکن است به نشانهگذاری گسترشیافتهٔ تحدیدکنندهٔ glob بهصورت (#q:s/.../.../) نیاز داشته باشند تا پوسته بتواند عبارت را بهعنوان تحدیدکنندهٔ glob تشخیص دهد. علاوه بر این، توجه داشته باشید که الگوهای نادرست در جایگزینی مشمول گزینهٔ NO_BAD_PATTERN نمیشوند و بنابراین موجب خطا خواهند شد..PP هنگامی که HIST_SUBST_PATTERN تنظیم شده باشد، l میتواند با یک # آغاز شود تا نشان دهد الگو باید در ابتدای رشتهای که قرار است جایگزین شود مطابقت یابد، و یک % میتواند در ابتدا یا پس از یک # ظاهر شود تا نشان دهد الگو باید در انتهای رشتهای که قرار است جایگزین شود مطابقت یابد. علامتهای % یا # را میتوان با دو بکاسلش نقلقول کرد.
برای مثال، قطعه کد تولید نام فایل زیر با گزینهٔ EXTENDED_GLOB:
print -r -- *.c(#q:s/#%(#b)s(*).c/'S${match[1]}.C'/)
بسط *.c را گرفته و توصیفکنندههای glob را در عبارت (#q...) اعمال میکند، که شامل یک اصلاحکنندهٔ جایگزینی لنگرانداختهشده به ابتدا و انتهای هر کلمه (#%) است. این کار ارجاعهای به عقب ((#b)) را فعال میکند، به طوری که زیرعبارت داخل پرانتز در رشتهٔ جایگزین به صورت ${match[1]} در دسترس است. رشتهٔ جایگزین نقلقول شده است تا پارامتر پیش از شروع تولید نام فایل جایگزین نشود.
اصلاحکنندههای f، F، w و W زیر تنها با بسط پارامتر و تولید نام فایل کار میکنند. آنها در اینجا فهرست شدهاند تا یک مرجع واحد برای تمام اصلاحکنندهها فراهم شود.
- f
- اصلاحکنندهٔ بلافاصله بعدی (بدون دونقطه) را تا زمانی تکرار میکند که کلمهٔ حاصل دیگر تغییری نکند.
- F:expr:
- مانند f، اما اگر عبارت expr به n ارزیابی شود، تنها n بار تکرار میکند. هر نویسهای میتواند بهجای `:' استفاده شود؛ اگر از `('، `['، یا `{' به عنوان جداکنندهٔ آغازین استفاده شود، جداکنندهٔ پایانی باید به ترتیب ')'، `]'، یا `}' باشد.
- w
- باعث میشود اصلاحکنندهٔ بلافاصله بعدی روی هر کلمه در رشته عمل کند.
- W:sep:
- مانند w، اما کلمات بخشهایی از رشته در نظر گرفته میشوند که توسط sep جدا شدهاند. هر نویسهای میتواند بهجای `:' استفاده شود؛ پرانتزهای آغازین به صورت ویژه مدیریت میشوند، بالا را ببینید.
جایگزینی فرایند (PROCESS SUBSTITUTION)
هر بخش از یک آرگومان دستور که به شکل `<(list)'، `>(list)' یا `=(list)' باشد، مشمول جایگزینی فرایند است. این عبارت میتواند با رشتههای دیگر پیش یا پس از خود همراه شود، به جز اینکه برای جلوگیری از تداخل با رشتهها و الگوهای رایج، آخرین شکل باید در ابتدای یک آرگومان دستور ظاهر شود، و این اشکال تنها در زمان تجزیهٔ اولیهٔ آرگومانهای دستور یا انتساب بسط مییابند. جایگزینیهای فرایند میتوانند پس از عملگرهای تغییر مسیر استفاده شوند؛ در این حالت، جایگزینی باید بدون هیچ رشتهٔ انتهایی ظاهر شود.
توجه داشته باشید که `<<(list)' یک نحو ویژه نیست؛ این معادل `< <(list)' است که ورودی استاندارد را از نتیجهٔ جایگزینی فرایند تغییر مسیر میدهد. بنابراین تمام مستندات بعدی اعمال میشوند. شکل دوم (با فاصله) برای وضوح بیشتر توصیه میشود.
در حالت اشکال < یا >، شل دستورات موجود در list را به عنوان یک زیرفرایند از کار در حال اجرای خط فرمان شل اجرا میکند. اگر سیستم از سازوکار /dev/fd پشتیبانی کند، آرگومان دستور نام فایل دستگاه متناظر با یک توصیفگر فایل است؛ در غیر این صورت، اگر سیستم از لولههای نامگذاریشده (FIFO) پشتیبانی کند، آرگومان دستور یک لولهٔ نامگذاریشده خواهد بود. اگر شکل همراه با > انتخاب شود، نوشتن روی این فایل ویژه ورودی را برای list فراهم میکند. اگر از < استفاده شود، فایلی که به عنوان آرگومان ارسال شده است به خروجی فرایند list متصل خواهد شد. برای مثال،
paste <(cut -f1 file1) <(cut -f3 file2) | tee >(process1) >(process2) >/dev/null
به ترتیب فیلدهای ۱ و ۳ را از فایلهای file1 و file2 برش داده، نتایج را کنار هم قرار میدهد، و آن را به فرایندهای process1 و process2 ارسال میکند.
اگر بهجای <(...) از =(...) استفاده شود، آنگاه فایلی که به عنوان آرگومان ارسال میشود نام یک فایل موقت حاوی خروجی فرایند list خواهد بود. این میتواند بهجای شکل < برای برنامهای استفاده شود که انتظار دارد روی فایل ورودی lseek (نگاه کنید به lseek(2)) انجام دهد.
یک بهینهسازی برای جایگزینیهایی به شکل =(<<<arg) وجود دارد، که در آن arg یک آرگومان تککلمهای برای تغییر مسیر here-string <<< است. این شکل نام فایلی را تولید میکند که حاوی مقدار arg پس از انجام هرگونه جایگزینی است. این کار کاملاً درون شل فعلی انجام میشود. این در عمل معکوس شکل ویژهٔ $(<arg) است که با arg مانند نام یک فایل رفتار کرده و آن را با محتویات فایل جایگزین میکند.
شکل = مفید است زیرا هر دو پیادهسازی /dev/fd و لولهٔ نامگذاریشده برای <(...) دارای معایبی هستند. در حالت اول، برخی برنامهها ممکن است به طور خودکار توصیفگر فایل مربوطه را پیش از بررسی فایل در خط فرمان ببندند، به ویژه اگر این کار به دلایل امنیتی لازم باشد، مانند زمانی که برنامه به صورت setuid اجرا میشود. در حالت دوم، اگر برنامه عملاً فایل را باز نکند، زیرشلی که تلاش میکند از لوله بخواند یا در آن بنویسد (در یک پیادهسازی معمول؛ سیستمعاملهای مختلف ممکن است رفتار متفاوتی داشته باشند) برای همیشه مسدود شده و باید صریحاً کشته شود. در هر دو حالت، شل در واقع اطلاعات را با استفاده از یک لوله ارائه میدهد، به طوری که برنامههایی که انتظار دارند روی فایل lseek (نگاه کنید به lseek(2)) انجام دهند کار نخواهند کرد.
همچنین توجه داشته باشید که مثال قبلی را میتوان به شکلی فشردهتر و کارآمدتر (به شرطی که گزینهٔ MULTIOS تنظیم شده باشد) به صورت زیر نوشت:
paste <(cut -f1 file1) <(cut -f3 file2) > >(process1) > >(process2)
شل برای پیادهسازی دو جایگزینی فرایند آخر در مثال بالا، بهجای FIFOها از لولهها (pipes) استفاده میکند.
مشکل دیگری با >(process) وجود دارد؛ هنگامی که این عبارت به یک دستور خارجی متصل میشود، شل والد منتظر پایان یافتن process نمیماند و بنابراین دستوری که بلافاصله پس از آن میآید نمیتواند به کامل بودن نتایج اتکا کند. مشکل و راهحل همانند موارد توصیفشده در بخش MULTIOS در zshmisc(1) است. بنابراین در نسخهای سادهشده از مثال بالا:
paste <(cut -f1 file1) <(cut -f3 file2) > >(process)
(توجه داشته باشید که هیچ MULTIOSی دخیل نیست)، process از دیدگاه شل والد به صورت ناهمگام اجرا خواهد شد. راهکار جایگزین این است:
{ paste <(cut -f1 file1) <(cut -f3 file2) } > >(process)
فرایندهای اضافی در اینجا از شل والد ایجاد میشوند که منتظر تکمیل آنها خواهد ماند.
مشکل دیگری هر زمان رخ میدهد که یک کار با جایگزینی که نیازمند یک فایل موقت است، توسط شل رها (disown) شود، از جمله حالتی که `&!' یا `&|' در انتهای دستوری حاوی یک جایگزینی ظاهر شود. در این حالت، از آنجا که شل دیگر این کار را به خاطر نمیآورد، فایل موقت پاکسازی نخواهد شد. یک راهکار استفاده از یک زیرشل است، برای مثال:
(mycmd =(myoutput)) &!
زیرا زیرشل منشعبشده منتظر پایان یافتن دستور مانده و سپس فایل موقت را حذف خواهد کرد.
یک راهکار کلی برای اطمینان از اینکه جایگزینی فرایند برای مدت زمانی مناسب باقی میماند، ارسال آن به عنوان یک پارامتر به یک تابع بینام شل است (قطعه کدی از شل که بلافاصله با حوزهٔ متغیرهای تابع اجرا میشود). برای مثال، این کد:.PP
() {
print File $1:
cat $1
} =(print This be the verse)
خروجیای شبیه به مورد زیر تولید میکند:
File /tmp/zsh6nU0kS: This be the verse
فایل موقتی که توسط جایگزینی فرایند ایجاد شده است، هنگام خروج تابع حذف خواهد شد.
گسترش پارامتر (PARAMETER EXPANSION)
نویسهٔ `$' برای آغاز گسترشهای پارامتر به کار میرود. برای مشاهدهٔ شرحی از پارامترها، از جمله آرایهها، آرایههای انجمنی، و نمادگذاری زیرنویس جهت دسترسی به عناصر منفرد آرایه، zshparam(1) را ببینید.
بهویژه به این نکته توجه کنید که کلمات پارامترهای نقلقولنشده بهطور خودکار بر اساس فاصلهٔ خالی (whitespace) تفکیک نمیشوند، مگر آنکه گزینهٔ SH_WORD_SPLIT تنظیم شده باشد؛ برای جزئیات بیشتر به مراجع این گزینه در ادامه نگاه کنید. این یک تفاوت مهم نسبت به سایر پوستهها است. با این حال، همانند دیگر پوستهها، کلمات تهی (null) از گسترش پارامترهای نقلقولنشده حذف میشوند.
با گزینههای پیشفرض، پس از مقداردهیهای زیر:
array=("first word" "" "third word")
scalar="only word"
آنگاه $array دو کلمهٔ `first word' و `third word' را جایگزین میکند، و $scalar تککلمهٔ `only word' را جایگزین مینماید. توجه داشته باشید که عنصر دوم array حذف شد. پارامترهای اسکالر نیز در صورتی که مقدارشان تهی (خالی) باشد میتوانند حذف شوند. برای جلوگیری از این حذف، نقلقول را به صورت زیر به کار ببرید: "$scalar" برای اسکالرها و "${array[@]}" یا "${(@)array}" برای آرایهها. (دو شکل اخیر معادل یکدیگرند.)
گسترشهای پارامتر میتوانند شامل پرچمها باشند، مانند `${(@kv)aliases}'، و عملگرهای دیگر، مانند `${PREFIX:-"/usr/local"}'. گسترشهای پارامتر میتوانند تودرتو نیز باشند. این مباحث در ادامه معرفی خواهند شد. قواعد کامل پیچیده هستند و در انتها به آنها اشاره شده است.
در گسترشهای مورد بحث زیر که نیازمند یک الگو هستند، شکل الگو همان است که برای تولید نام فایل به کار میرود؛ بخش `Filename Generation' را ببینید. توجه داشته باشید که این الگوها، به همراه متن جایگزین هر تعویض، خود مشمول گسترش پارامتر، جایگزینی دستور، و گسترش محاسباتی هستند. علاوه بر عملیات زیر، اصلاحکنندههای دونقطه که در بخش `Modifiers' از بخش `History Expansion' توضیح داده شدهاند نیز قابل اعمال هستند: برای مثال، ${i:s/foo/bar/} عمل جایگزینی رشته را بر روی گسترش پارامتر $i انجام میدهد.
در توضیحات زیر، `word' به یک کلمهٔ منفرد جایگزینشده در خط فرمان اشاره دارد، نه لزوماً کلمهای که با فاصله جدا شده باشد.
- ${name}
- مقدار پارامتر name، در صورت وجود، جایگزین میشود. اگر قرار باشد گسترش با یک حرف، رقم، یا زیرخط دنبال شود که نباید به عنوان بخشی از name تفسیر گردد، استفاده از آکولاد الزامی است. علاوه بر این، اشکال پیچیدهتر جایگزینی معمولاً نیازمند وجود آکولاد هستند؛ استثناها، که تنها در صورت تنظیم نبودن گزینهٔ KSH_ARRAYS اعمال میشوند، عبارتند از یک زیرنویس منفرد یا هر اصلاحکنندهٔ دونقطه که پس از نام ظاهر میشود، یا هر یک از نویسههای `^'، `='، `~'، `#' یا `+' که پیش از نام بیایند، که همگی با آکولاد یا بدون آن کار میکنند.
اگر name یک پارامتر آرایهای باشد و گزینهٔ KSH_ARRAYS تنظیم نشده باشد، مقدار هر عنصر از name جایگزین میشود، یک عنصر در هر کلمه. در غیر این صورت، گسترش تنها به یک کلمه میانجامد؛ با KSH_ARRAYS، این همان عنصر نخست آرایه است. هیچ تفکیک فیلدی بر روی نتیجه انجام نمیگیرد مگر آنکه گزینهٔ SH_WORD_SPLIT تنظیم شده باشد. پرچمهای = و s:string: را نیز ببینید.
- ${+name}
- اگر name نام یک پارامتر مقداردهیشده باشد `1' جایگزین میشود، در غیر این صورت `0' جایگزین خواهد شد.
- ${name-word}
- ${name:-word}
- اگر name مقداردهی شده باشد، یا در شکل دوم غیرتهی (non-null) باشد، مقدار آن جایگزین میشود؛ در غیر این صورت word جایگزین میگردد. در شکل دوم میتوان name را حذف کرد، که در این حالت همواره word جایگزین میشود.
- ${name+word}
- ${name:+word}
- اگر name مقداردهی شده باشد، یا در شکل دوم غیرتهی باشد، word جایگزین میشود؛ در غیر این صورت هیچچیز جایگزین نمیشود.
- ${name=word}
- ${name:=word}
- ${name::=word}
- در شکل اول، اگر name مقداردهینشده باشد مقدار آن برابر با word قرار میگیرد؛ در شکل دوم، اگر name مقداردهینشده یا تهی باشد مقدار آن برابر با word قرار میگیرد؛ و در شکل سوم، بدون قید و شرط name برابر با word تنظیم میشود. در تمامی اشکال، سپس مقدار name جایگزین میگردد.
- ${name?word}
- ${name:?word}
- در شکل اول، اگر name مقداردهی شده باشد، یا در شکل دوم اگر name هم مقداردهی شده و هم غیرتهی باشد، مقدار آن جایگزین میشود؛ در غیر این صورت، word چاپ شده و از پوسته خروج حاصل میشود. پوستههای تعاملی در عوض به اعلان خط فرمان بازمیگردند. اگر word حذف شود، یک پیام استاندارد چاپ میشود. توجه داشته باشید که word حتی در صورتی که مقدارش بر روی خط فرمان جایگزین نشود نیز گسترش مییابد.
در هر یک از عبارتهای فوق که متغیری را ارزیابی کرده و یک word جایگزین را قرار میدهند، توجه کنید که میتوانید از نقلقول استاندارد پوسته در مقدار word برای لغو انتخابی تفکیک انجامشده توسط گزینهٔ SH_WORD_SPLIT و پرچم = استفاده کنید، اما نمیتوانید تفکیک ناشی از پرچم s:string: را لغو نمایید.
در عبارتهای زیر، هنگامی که name یک آرایه باشد و جایگزینی نقلقول نشده باشد، یا اگر پرچم `(@)' یا ساختار name[@] استفاده شود، تطابق و جایگزینی به طور جداگانه بر روی هر عنصر آرایه انجام میگیرد.
- ${name#pattern}
- ${name##pattern}
- اگر pattern با ابتدای مقدار name مطابقت داشته باشد، مقدار name با حذف بخش منطبق جایگزین میشود؛ در غیر این صورت، صرفاً مقدار name جایگزین میگردد. در شکل نخست، کوتاهترین الگوی منطبق ترجیح داده میشود؛ در شکل دوم، بلندترین الگوی منطبق در اولویت است.
- ${name%pattern}
- ${name%%pattern}
- اگر pattern با انتهای مقدار name مطابقت داشته باشد، مقدار name با حذف بخش منطبق جایگزین میشود؛ در غیر این صورت، صرفاً مقدار name جایگزین میگردد. در شکل نخست، کوتاهترین الگوی منطبق ترجیح داده میشود؛ در شکل دوم، بلندترین الگوی منطبق در اولویت است.
- ${name:#pattern}
- اگر pattern با مقدار name مطابقت داشته باشد، رشتهٔ خالی جایگزین میشود؛ در غیر این صورت، صرفاً مقدار name جایگزین خواهد شد. اگر name یک آرایه باشد، عناصر منطبق آرایه حذف میشوند (برای حذف عناصر غیرمنطبق از پرچم `(M)' استفاده کنید)..TP ${name:|arrayname} اگر arrayname نام (توجه: نه محتویات) یک متغیر آرایهای باشد، آنگاه هر عنصری که در arrayname وجود دارد از جایگزینیِ name حذف میشود. اگر جایگزینی اسکالر باشد، خواه به این دلیل که name یک متغیر اسکالر است یا عبارت درون نقلقول قرار گرفته باشد، عناصر arrayname در عوض در برابر کل عبارت سنجیده میشوند.
- ${name:*arrayname}
- مشابه جایگزینی قبلی است، اما در جهت عکس، بهطوری که مدخلهای موجود در هر دو (هم در جایگزینی اصلی و هم بهعنوان عناصر arrayname) حفظ شده و سایر موارد حذف میشوند.
- ${name:^arrayname}
- ${name:^^arrayname}
- دو آرایه را در هم میتند (زیپ میکند)، بهگونهای که طول آرایهٔ خروجی دو برابر کوتاهترین (برای «:^^»، بلندترین) آرایه از بین name و arrayname خواهد بود و عناصر بهصورت متناوب از آنها انتخاب میشوند. برای «:^»، اگر یکی از آرایههای ورودی طولانیتر باشد، با رسیدن به انتهای آرایهٔ کوتاهتر خروجی متوقف میشود. بنابراین،
a=(1 2 3 4); b=(a b); print ${a:^b}
خروجی «1 a 2 b» را تولید میکند. برای «:^^»، ورودی تا زمانی تکرار میشود که تمام آرایهٔ طولانیتر مصرف شود و دستور بالا خروجی «1 a 2 b 3 a 4 b» را تولید خواهد کرد.
یک یا هر دو ورودی میتوانند اسکالر باشند، که در این صورت مانند یک آرایه به طول ۱ که تنها عنصر آن همان اسکالر است رفتار میشود. اگر هر یک از آرایهها خالی باشد، آرایهٔ دیگر بدون درج هیچ عنصر اضافی در خروجی قرار میگیرد.
در حال حاضر کد زیر «a b» و «1» را بهعنوان دو عنصر جداگانه خروجی میدهد، که میتواند غیرمنتظره باشد. دستور دوم print یک راهکار جایگزین ارائه میدهد که حتی در صورت تغییر این رفتار، همچنان به درستی کار خواهد کرد.
a=(a b); b=(1 2); print -l "${a:^b}"; print -l "${${a:^b}}"
- ${name:offset}
- ${name:offset:length}
- این نحو نتایجی مشابه با اندیسگذاری پارامتر به فرم $name[start,end] ارائه میدهد، اما با سایر پوستهها سازگار است؛ توجه داشته باشید که هر دو مقدار offset و length متفاوت از مؤلفههای اندیس تفسیر میشوند.
اگر offset نامنفی باشد، در صورتی که متغیر name یک اسکالر باشد، محتویات را از offset نویسه پس از نخستین نویسهٔ رشته جایگزین میکند، و اگر name یک آرایه باشد عناصر را از offset عنصر پس از نخستین عنصر جایگزین مینماید. اگر length مشخص شده باشد، به همان تعداد نویسه یا عنصر را جایگزین میکند، در غیر این صورت کل باقیماندهٔ اسکالر یا آرایه جایگزین خواهد شد.
یک offset مثبت همواره بهعنوان انحراف یک نویسه یا عنصر در name نسبت به نخستین نویسه یا عنصر آرایه در نظر گرفته میشود (این با نحو بومی اندیس در zsh متفاوت است). از این رو، بدون در نظر گرفتن تنظیمات گزینهٔ KSH_ARRAYS، مقدار 0 به نخستین نویسه یا عنصر اشاره دارد.
یک افست منفی از انتهای اسکالر یا آرایه به سمت عقب شمارش میکند، بهطوری که -1 متناظر با آخرین نویسه یا عنصر است و به همین ترتیب.
وقتی مثبت باشد، length از موقعیت offset به سمت انتهای اسکالر یا آرایه شمارش میشود. وقتی منفی باشد، length از انتها به عقب میشمارد. اگر این عمل منجر به موقعیتی کوچکتر از offset شود، یک پیام خطا چاپ شده و هیچ چیزی جایگزین نمیشود.
گزینهٔ MULTIBYTE رعایت میشود، یعنی افست و طول در موارد مقتضی نویسههای چندبایتی را میشمارند.
مقادیر offset و length همان مجموعه از جایگزینیهای پوسته را مانند انتساب اسکالر طی میکنند؛ علاوه بر این، سپس تحت ارزیابی حسابی قرار میگیرند. بنابراین، به عنوان مثال
print ${foo:3}
print ${foo: 1 + 2}
print ${foo:$(( 1 + 2))}
print ${foo:$(echo 1 + 2)}
همگی اثری یکسان دارند؛ یعنی در صورتی که جایگزینی در حالت عادی یک اسکالر بازگرداند، رشته را با شروع از چهارمین نویسهٔ $foo استخراج میکنند، و اگر $foo یک آرایه بازگرداند، آرایه را با شروع از چهارمین عنصر استخراج خواهند کرد. توجه داشته باشید که با فعال بودن گزینهٔ KSH_ARRAYS متغیر $foo همیشه یک اسکالر بازمیگرداند (صرفنظر از استفاده از نحو افست) و برای استخراج عناصر آرایهای به نام foo، شکلی مانند ${foo[*]:3} لازم است.
اگر offset منفی باشد، علامت - نباید بلافاصله پس از : ظاهر شود، زیرا این بیانگر شکل جایگزینیِ ${name:-word} است. در عوض، میتوان یک فاصله قبل از - قرار داد. علاوه بر این، نه offset و نه length نباید با یک نویسهٔ الفبایی یا & شروع شوند، چرا که اینها برای مشخص کردن تغییردهندههای سبکِ تاریخچه به کار میروند. برای جایگزینی یک مقدار از یک متغیر، روش توصیهشده این است که پیش از آن یک $ قرار گیرد تا مقصود را مشخص کند (جایگزینی پارامتر میتواند به راحتی ناخوانا شود)؛ با این حال، از آنجا که ارزیابی حسابی انجام میشود، عبارت ${var: offs} نیز کار کرده و افست را از $offs واکشی میکند.
برای سازگاری بیشتر با سایر پوستهها، یک حالت خاص برای افست 0 آرایه وجود دارد. این معمولاً به نخستین عنصر آرایه دسترسی پیدا میکند. با این حال، اگر جایگزینی به آرایهٔ پارامترهای مکانی (مانند $@ یا $*) اشاره داشته باشد، افست 0 در عوض به $0، افست 1 به $1، و به همین ترتیب اشاره میکند. به عبارت دیگر، آرایهٔ پارامترهای مکانی عملاً با افزودن $0 به ابتدای آن گسترش مییابد. بنابراین ${*:0:1} مقدار $0 و ${*:1:1} مقدار $1 را جایگزین میکند.
- ${name/pattern/repl}
- ${name//pattern/repl}
- ${name:/pattern/repl}
- طولانیترین تطابق ممکن از pattern را در بسط پارامتر name با رشتهٔ repl جایگزین میکند. شکل اول فقط نخستین رخداد، شکل دوم تمام رخدادها، و شکل سوم تنها در صورتی جایگزین میکند که pattern با کل رشته مطابقت داشته باشد. هر دو مورد pattern و repl مشمول جایگزینی درون نقلقول مضاعف (double-quoted) میشوند، بنابراین عباراتی مانند ${name/$opat/$npat} کار خواهند کرد، اما از این قاعدهٔ معمول پیروی میکنند که با نویسههای الگو در $opat رفتار ویژهای نمیشود مگر اینکه گزینهٔ GLOB_SUBST تنظیم شده باشد یا $opat در عوض به صورت ${~opat} جایگزین شود.
الگوی pattern میتواند با یک «#» شروع شود، که در این حالت pattern باید در ابتدای رشته تطابق یابد، یا با «%»، که در این حالت باید در انتهای رشته تطابق یابد، یا با «#%» که در این صورت pattern باید با کل رشته مطابقت داشته باشد. رشتهٔ repl میتواند خالی باشد، که در این حالت «/» پایانی نیز میتواند حذف شود. برای نقلقول کردن «/» پایانی در سایر موارد، باید یک بکاسلش منفرد قبل از آن قرار گیرد؛ اگر «/» درون یک پارامتر جایگزینشده قرار داشته باشد، این کار لازم نیست. همچنین توجه داشته باشید که «#»، «%» و «#%» در صورتی که درون یک پارامتر جایگزینشده قرار گیرند، حتی در ابتدای آن، فعال نخواهند بود.
اگر پس از اعمال قواعد نقلقول، عبارت ${name} به یک آرایه بسط یابد، جایگزینیها روی هر عنصر بهطور جداگانه اعمال میشوند. همچنین به اثر پرچمهای بسط پارامتر I و S در ادامه توجه کنید؛ با این حال، پرچمهای M، R، B، E و N کاربردی ندارند.
برای مثال،
foo="twinkle twinkle little star" sub="t*e" rep="spy"
print ${foo//${~sub}/$rep}
print ${(S)foo//${~sub}/$rep}
در اینجا، «~» تضمین میکند که با متن $sub به جای یک رشتهٔ ساده، بهعنوان یک الگو رفتار شود. در حالت اول، طولانیترین تطابق برای t*e جایگزین شده و نتیجه «spy star» خواهد بود، در حالی که در حالت دوم، کوتاهترین تطابقها انتخاب شده و نتیجه «spy spy lispy star» خواهد شد. ${#spec} اگر spec یکی از جایگزینیهای بالا باشد، طول کاراکتری نتیجه بهجای خود نتیجه جایگزین میشود. اگر spec یک عبارت آرایهای باشد، تعداد عناصر نتیجه جایگزین میشود. این امر اثر جانبی دارد که الحاق (joining) حتی در فرمهای درون گیومه نیز نادیده گرفته میشود، که ممکن است بر سایر زیرعبارتها در spec تأثیر بگذارد. توجه داشته باشید که هنگام ترکیب این فرمها، «^»، «=»، و «~» که در ادامه آمدهاند، باید در سمت چپ «#» قرار گیرند.
اگر گزینهٔ POSIX_IDENTIFIERS تنظیم نشده باشد، و spec یک نام ساده باشد، آکولادها اختیاری هستند؛ این امر حتی برای پارامترهای خاص نیز صادق است، بنابراین برای مثال $#- و $#* به ترتیب طول رشتهٔ $- و آرایهٔ $* را میگیرند. اگر POSIX_IDENTIFIERS تنظیم شده باشد، برای اینکه با # به این شیوه رفتار شود، استفاده از آکولاد الزامی است.
- ${^spec}
- ${^^spec}
- گزینهٔ RC_EXPAND_PARAM را برای ارزیابی spec فعال میکند؛ اگر «^» دو بار تکرار شود، آن را غیرفعال میکند. هنگامی که این گزینه تنظیم شده باشد، بسطهای آرایه به فرم foo${xx}bar، که در آن پارامتر xx روی (a b c) تنظیم شده است، بهجای مقدار پیشفرض «fooa b cbar»، با «fooabar foobbar foocbar» جایگزین میشوند. توجه داشته باشید که بنابراین یک آرایهٔ خالی باعث حذف تمامی آرگومانها خواهد شد.
بهطور داخلی، هر یک از این بسطها به فهرست معادل برای بسط آکولاد تبدیل میشود. برای مثال، ${^var} به {$var[1],$var[2],...} تبدیل میشود و همانطور که در بخش `Brace Expansion' در زیر آمده پردازش میگردد: با این حال، توجه داشته باشید که این بسط بلافاصله انجام میشود و هرگونه بسط آکولاد صریح بعداً رخ میدهد. اگر تفکیک کلمات (word splitting) نیز فعال باشد، ممکن است خود $var[N] نیز به عناصر متفاوتی در فهرست تفکیک شوند.
- ${=spec}
- ${==spec}
- تفکیک کلمات را با استفاده از قواعد SH_WORD_SPLIT در حین ارزیابی spec انجام میدهد، اما بدون توجه به اینکه پارامتر درون گیومه دوتایی باشد یا خیر؛ اگر «=» دو بار تکرار شود، آن را غیرفعال میکند. این کار بسطهای پارامتر را مجبور میکند قبل از جایگزینی، با استفاده از IFS بهعنوان جداکننده به کلمات مجزا تفکیک شوند. این عمل بهطور پیشفرض در بیشتر شلهای دیگر انجام میشود.
توجه داشته باشید که تفکیک روی word در فرمهای انتسابِ spec، پیش از انجام انتساب به name اعمال میشود. این امر بر نتیجهٔ انتسابهای آرایهای با پرچم A تأثیر میگذارد.
- ${~spec}
- ${~~spec}
- گزینهٔ GLOB_SUBST را برای ارزیابی spec فعال میکند؛ اگر «~» دو بار تکرار شود، آن را غیرفعال میکند. هنگامی که این گزینه تنظیم شده باشد، رشتهٔ حاصل از بسط در هر کجا که ممکن باشد بهعنوان یک الگو تفسیر خواهد شد، مانند بسط نام فایل و تولید نام فایل (filename generation) و زمینههای تطبیق الگو مانند سمت راست عملگرهای «=» و «!=» در شرطها.
در جایگزینیهای تودرتو، توجه داشته باشید که اثر ~ بر نتیجهٔ سطح جاری جایگزینی اعمال میشود. یک عملیات الگوی احاطهکننده بر روی نتیجه ممکن است آن را لغو کند. از این رو، برای مثال، اگر پارامتر foo روی * تنظیم شده باشد، ${~foo//\*/*.c} با الگوی *.c جایگزین میشود که ممکن است توسط تولید نام فایل بسط یابد، اما ${${~foo}//\*/*.c} به رشتهٔ *.c جایگزین میشود که دیگر بسط نخواهد یافت.
اگر یک عبارت پارامتری از نوع ${...} یا یک جایگزینی دستور از نوع $(...) بهجای name در بالا استفاده شود، ابتدا آن بسط مییابد و نتیجه به گونهای استفاده میشود که گویی مقدار name است. بنابراین، امکان انجام عملیاتهای تودرتو وجود دارد: ${${foo#head}%tail} مقدار $foo را در حالی که هر دو «head» و «tail» از آن حذف شدهاند جایگزین میکند. فرم به همراه $(...) اغلب در ترکیب با پرچمهای توصیفشده در ادامه مفید است؛ مثالهای زیر را ببینید. هر name یا ${...} تودرتو در یک بسط پارامتر همچنین میتواند با یک عبارت اندیس (subscript expression) همراه باشد، همانطور که در Array Parameters در zshparam(1) توصیف شده است.
توجه داشته باشید که ممکن است گیومه دوتایی در اطراف عبارتهای تودرتو ظاهر شود، که در این صورت فقط بخش داخل آن بهعنوان نقلشده (quoted) در نظر گرفته میشود؛ برای مثال، ${(f)"$(foo)"} نتیجهٔ $(foo) را درون گیومه قرار میدهد، اما پرچم «(f)» (پایین را ببینید) با استفاده از قواعد بسطهای بدون گیومه اعمال میشود. همچنین توجه داشته باشید که خود گیومهها در این زمینه تودرتو هستند؛ برای مثال در "${(@f)"$(foo)"}"، دو مجموعه گیومه وجود دارد، یکی کل عبارت را احاطه کرده و دیگری (اضافی) مانند قبل $(foo) را احاطه میکند. اگر بلافاصله پس از آکولاد باز یک پرانتز باز بیاید، رشتهٔ متنی تا پرانتز بستهٔ متناظر به عنوان فهرستی از پرچمها در نظر گرفته میشود. در مواردی که تکرار یک پرچم معنادار است، نیازی نیست تکرارها متوالی باشند؛ برای مثال، `(q%q%q)' همان معنای عبارت خواناتر `(%%qqq)' را دارد. پرچمهای زیر پشتیبانی میشوند:
- #
- کلمات حاصل را به عنوان عبارات عددی ارزیابی کرده و آنها را به عنوان کدهای نویسه تفسیر میکند. نویسههای متناظر را در خروجی قرار میدهد. توجه داشته باشید که این حالت کاملاً با استفاده از # بدون پرانتز متفاوت است.
اگر گزینهٔ MULTIBYTE تنظیم شده باشد و عدد بزرگتر از 127 باشد (یعنی یک نویسهٔ ASCII نباشد)، به عنوان یک نویسهٔ یونیکد در نظر گرفته میشود.
- %
- تمام توالیهای گریز % در کلمات حاصل را به همان روش اعلانات (prompts) بسط میدهد (بخش EXPANSION OF PROMPT SEQUENCES در zshmisc(1) را ببینید). اگر این پرچم دو بار داده شود، بسته به تنظیمات گزینههای PROMPT_PERCENT، PROMPT_SUBST و PROMPT_BANG، بسط کامل اعلان روی کلمات حاصل انجام میشود.
- @
- در داخل گیومههای دوگانه، عناصر آرایه در کلمات جداگانه قرار میگیرند. برای مثال، `"${(@)foo}"' معادل `"${foo[@]}"' و `"${(@)foo[1,2]}"' همانند `"$foo[1]" "$foo[2]"' است. این با تفکیک فیلد توسط پرچمهای f، s یا z، که همچنان درون هر عنصر آرایه اعمال میشود، متفاوت است.
- A
- جایگزینی را به یک عبارت آرایهای تبدیل میکند، حتی اگر در غیر این صورت اسکالر باشد. این تقدم کمتری نسبت به اندیسگذاری دارد، بنابراین برای اینکه اندیسها روی عناصر آرایه اعمال شوند به یک سطح بسط تودرتو نیاز است. بدین ترتیب ${${(A)name}[1]} زمانی که name یک اسکالر باشد مقدار کامل name را نتیجه میدهد.
این پرچم یک پارامتر آرایهای را با `${...=...}'، `${...:=...}' یا `${...::=...}' مقداردهی میکند. اگر این پرچم تکرار شود (مانند `AA')، یک پارامتر آرایهٔ انجمنی را مقداردهی میکند. مقداردهی قبل از مرتبسازی یا فاصلهگذاری (padding) انجام میشود؛ اگر تفکیک فیلد فعال باشد، بخش word قبل از مقداردهی تفکیک میشود. بخش name ممکن است یک بازهٔ اندیسگذاریشده برای آرایههای معمولی باشد؛ هنگام مقداردهی یک آرایهٔ انجمنی، بخش word باید به یک آرایه تبدیل شود، برای مثال با استفاده از `${(AA)=name=...}' برای فعالسازی تفکیک فیلد.
بافت پیرامونی مانند تودرتویی بیشتر یا استفاده از مقدار در یک انتساب اسکالر ممکن است باعث شود که آرایه دوباره به یک رشتهٔ واحد متصل شود.
- a
- بر اساس ترتیب اندیس آرایه مرتب میکند؛ در صورت ترکیب با `O'، به ترتیب معکوس اندیس آرایه مرتب میکند. توجه داشته باشید که بنابراین `a' معادل حالت پیشفرض است اما `Oa' برای بهدست آوردن عناصر یک آرایه با ترتیب معکوس مفید است.
- b
- تنها نویسههایی را که برای تطبیق الگو خاص هستند، با بکاسلش نقلقول میکند. این زمانی مفید است که قرار باشد محتویات متغیر با استفاده از GLOB_SUBST، از جمله کلید ${~...} بررسی شود.
نقلقول کردن با استفاده از یکی از پرچمهای خانوادهٔ q برای این منظور کار نمیکند زیرا نقلقولها از نویسههای غیرالگویی توسط GLOB_SUBST حذف نمیشوند. به عبارت دیگر،
pattern=${(q)str}
[[ $str = ${~pattern} ]]
اگر $str برابر با `a*b' باشد کار میکند اما اگر `a b' باشد کار نمیکند، در حالی که
pattern=${(b)str}
[[ $str = ${~pattern} ]]
برای هر مقدار ممکنی از $str همیشه درست است.
- c
- همراه با ${#name}، تعداد کل نویسههای یک آرایه را میشمارد، گویی عناصر با فاصله بین آنها متصل شدهاند. این یک پیوند (join) واقعی آرایه نیست، بنابراین سایر عبارتهای استفادهشده با این پرچم ممکن است قبل از شمارش، روی عناصر آرایه تأثیر بگذارند.
- C
- حرف اول کلمات حاصل را بزرگ (Capitalize) میکند. «کلمات» در این مورد به توالیهایی از نویسههای الفباییعددی اطلاق میشود که با نویسههای غیرالفباییعددی جدا شدهاند، نه کلماتی که از تفکیک فیلد حاصل میشوند.
- D
- فرض میکند رشته یا عناصر آرایه حاوی دایرکتوریها هستند و تلاش میکند بخش آغازین آنها را با نامها جایگزین کند. سپس باقیماندهٔ مسیر (یا کل آن، اگر بخش آغازین جایگزین نشده باشد) نقلقول میشود تا کل رشته بتواند به عنوان یک آرگومان پوسته استفاده شود. این عمل برعکس جایگزینی `~' است: بخش FILENAME EXPANSION را در زیر ببینید.
- e
- بسطهای تککلمهای پوسته، یعنی بسط پارامتر، جایگزینی دستور و بسط حسابی را روی نتیجه انجام میدهد. چنین بسطهایی میتوانند تودرتو باشند اما بازگشت بیش از حد عمیق ممکن است اثرات غیرقابلپیشبینی داشته باشد.
- f
- نتیجهٔ بسط را در خطوط جدید (newlines) تفکیک میکند. این کوتاهنوشتی برای `ps:\n:' است.
- F
- کلمات آرایهها را با استفاده از خط جدید به عنوان جداکننده به یکدیگر متصل میکند. این کوتاهنوشتی برای `pj:\n:' است.
- g:opts:
- در صورتی که هیچ گزینهای داده نشده باشد (g::)، توالیهای گریز را مانند دستور توکار echo پردازش میکند. با گزینهٔ o، گریزهای هشتهشتی نیازی به صفر آغازین ندارند. با گزینهٔ c، توالیهایی مانند `^X' نیز پردازش میشوند. با گزینهٔ e، توالی `\M-t' و توالیهای مشابه را مانند دستور توکار print پردازش میکند. با هر دو گزینهٔ o و e، مانند دستور توکار print رفتار میکند به جز اینکه در هیچیک از این حالتها `\c' تفسیر نمیشود.
- i
- مرتبسازی را بدون حساسیت به حروف بزرگ و کوچک انجام میدهد. میتواند با `n' یا `O' ترکیب شود.
- k
- اگر name به یک آرایهٔ انجمنی اشاره داشته باشد، به جای مقادیر عناصر، کلیدها (نامهای عناصر) را جایگزین میکند. هنگام استفاده با اندیسها (از جمله آرایههای معمولی)، جایگزینی اندیسها یا کلیدها را اجبار میکند حتی اگر شکل اندیس به مقادیر اشاره داشته باشد. با این حال، این پرچم نمیتواند با بازههای اندیس ترکیب شود. با گزینهٔ KSH_ARRAYS، طبق معمول برای اعمال روی کل آرایه به اندیس `[*]' یا `[@]' نیاز است.
- L
- تمام حروف موجود در نتیجه را به حروف کوچک تبدیل میکند.
- n
- اعداد صحیح دهدهی را بهصورت عددی مرتب میکند؛ اگر اولین نویسههای متفاوت دو رشتهٔ مورد آزمایش رقم نباشند، مرتبسازی بهصورت لغوی است. با `+' و `-' رفتار ویژهای نمیشود؛ با آنها مانند هر غیررقم دیگری رفتار میشود. اعداد صحیحی با صفرهای آغازین بیشتر، قبل از اعدادی با صفرهای کمتر یا بدون صفر مرتب میشوند. از این رو آرایهٔ `foo+24 foo1 foo02 foo2 foo3 foo20 foo23' به ترتیبی که نشان داده شده مرتب میشود. میتواند با `i' یا `O' ترکیب شود.
- -
- مانند n، اما یک علامت منفی آغازین نشاندهندهٔ یک عدد صحیح دهدهی منفی است. علامت منفی آغازین که پس از آن یک عدد صحیح نیامده باشد، مرتبسازی عددی را فعال نمیکند. توجه داشته باشید که با علامتهای `+' رفتار ویژهای نمیشود (این ممکن است در آینده تغییر کند).
- o
- کلمات حاصل را به ترتیب صعودی مرتب میکند؛ اگر این پرچم به تنهایی بیاید، مرتبسازی بهصورت لغوی و حساس به حروف بزرگ و کوچک است (مگر اینکه محلیسازی (locale) آن را به حروف کوچک و بزرگ غیرحساس کند). مرتبسازی صعودی حالت پیشفرض برای انواع دیگر مرتبسازی است، بنابراین اگر با `a'، `i'، `n' یا `-' ترکیب شود نادیده گرفته میشود.
- O
- کلمات حاصل را به ترتیب نزولی مرتب میکند؛ `O' بدون `a'، `i'، `n' یا `-' به ترتیب لغوی معکوس مرتب میکند. میتواند با `a'، `i'، `n' یا `-' ترکیب شود تا ترتیب مرتبسازی را معکوس کند.
- P
- این پرچم مقدار پارامتر name را مجبور میکند تا به عنوان نام یک پارامتر دیگر تفسیر شود که مقدار آن در جای مناسب استفاده خواهد شد. توجه داشته باشید پرچمهایی که با یکی از دستورات خانوادهٔ typeset تنظیم شدهاند (بهویژه تبدیلات بزرگی/کوچکی حروف) بر روی مقدار name که به این شیوه استفاده میشود اعمال نمیشوند. اگر به همراه یک جایگزینی متغیر تودرتو یا جایگزینی دستور استفاده شود، نتیجهٔ آن به همان شیوه به عنوان نام متغیر در نظر گرفته خواهد شد. برای مثال، اگر `foo=bar' و `bar=baz' را داشته باشید، رشتههای ${(P)foo}، ${(P)${foo}} و ${(P)$(echo bar)} به `baz' بسط خواهند یافت.
همچنین، اگر خود ارجاع تودرتو باشد، با عبارتی که دارای پرچم است طوری رفتار میشود که گویی مستقیماً با نام متغیر جایگزین شده است. اگر این جایگزینی تودرتو آرایهای با بیش از یک کلمه تولید کند، یک خطا به شمار میرود. برای مثال، اگر `name=assoc' باشد به طوری که متغیر assoc یک آرایهٔ انجمنی است، آنگاه `${${(P)name}[elt]}' به عنصری از آرایهٔ انجمنی با زیرنویس `elt' اشاره دارد.
- q
- کاراکترهایی را که برای شل معنای ویژهای دارند در کلمات حاصل با بکاسلش نقلقول (quote) میکند؛ کاراکترهای غیرقابلچاپ یا نامعتبر با استفاده از قالب $'\NNN'، با نقلقول جداگانه برای هر هشتبیت (octet) نقلقول میشوند.
اگر این پرچم دو بار مشخص شود، کلمات حاصل درون نقلقول تکی (single quotes) قرار میگیرند و اگر سه بار مشخص شود، کلمات درون نقلقول دوتایی (double quotes) قرار میگیرند؛ در این حالتها هیچ برخورد خاصی با کاراکترهای غیرقابلچاپ یا نامعتبر انجام نمیشود. اگر پرچم چهار بار مشخص شود، کلمات درون نقلقول تکی با یک پیشوند $ قرار میگیرند. توجه داشته باشید که در هر سه حالت، نقلقول کردن به صورت بدون شرط انجام میشود، حتی اگر این کار نحوهٔ تفسیر رشتهٔ حاصل توسط شل را تغییر ندهد.
اگر q- مشخص شود (تنها یک q مجاز است)، یک حالت حداقلی از نقلقول تکی به کار میرود که رشته را تنها در صورت نیاز برای محافظت از کاراکترهای ویژه درون نقلقول قرار میدهد. این حالت معمولاً خواناترین خروجی را ارائه میدهد.
اگر q+ مشخص شود، حالت گسترشیافتهای از نقلقول حداقلی به کار میرود که باعث میشود کاراکترهای غیرقابلچاپ با استفاده از $'...' نمایش داده شوند. این نقلقول مشابه روشی است که خروجی مقادیر توسط خانوادهٔ دستورات typeset استفاده میشود.
- Q
- یک سطح از نقلقولها را از کلمات حاصل حذف میکند.
- t
- در جایی که معمولاً مقدار متغیر نمایش مییابد، از رشتهای استفاده میکند که نوع متغیر را توصیف میکند. این رشته شامل کلیدواژههایی است که با خطتیره (`-') از هم جدا شدهاند. اولین کلیدواژه در رشته، نوع اصلی را توصیف میکند که میتواند یکی از `scalar'، `array'، `integer'، `float' یا `association' باشد. سایر کلیدواژهها نوع را با جزئیات بیشتر توصیف میکنند:
- local
- برای متغیرهای محلی
- left
- برای متغیرهای چپچینشده
- right_blanks
- برای متغیرهای راستچینشده با فاصلههای خالی ابتدایی
- right_zeros
- برای متغیرهای راستچینشده با صفرهای ابتدایی
- lower
- برای متغیرهایی که مقدار آنها هنگام بسط به حروف کوچک تبدیل میشود
- upper
- برای متغیرهایی که مقدار آنها هنگام بسط به حروف بزرگ تبدیل میشود
- readonly
- برای متغیرهای فقطخواندنی
- tag
- برای متغیرهای برچسبخورده
- tied
- برای متغیرهایی که به شیوهٔ PATH (فهرست جداشده با دونقطه) و path (آرایه) به متغیر دیگری پیوند خوردهاند، چه این متغیرها ویژه باشند و چه توسط کاربر با `typeset -T' تعریف شده باشند
- export
- برای متغیرهای صادرشده (export)
- unique
- برای آرایههایی که فقط اولین تکرار مقادیر تکراری را نگه میدارند
- hide
- برای متغیرهای دارای پرچم `hide'
- hideval
- برای متغیرهای دارای پرچم `hideval'
- special
- برای متغیرهای ویژهای که توسط شل تعریف شدهاند
- u
- تنها اولین رخداد هر کلمهٔ یکتا را بسط میدهد.
- U
- تمام حروف موجود در نتیجه را به حروف بزرگ تبدیل میکند.
- v
- در صورت استفاده با k، هر دو مقدار کلید و مقدار هر عنصر آرایهٔ انجمنی را (به عنوان دو کلمهٔ متوالی) جایگزین میکند. در صورت استفاده با زیرنویسها، حتی اگر حالت زیرنویس به نمایهها یا کلیدها اشاره کند، جایگزینی مقادیر را اجبار میکند.
- V
- هرگونه کاراکتر ویژه در کلمات حاصل را مرئی (قابلمشاهده) میکند.
- w
- همراه با ${#name}، کلمات را در آرایهها یا رشتهها میشمارد؛ پرچم s میتواند برای تعیین جداکنندهٔ کلمات استفاده شود.
- W
- مشابه w با این تفاوت که کلمات خالیِ بین جداکنندههای تکراری نیز شمرده میشوند.
- X
- با این پرچم، خطاهای تجزیه که در پرچمهای Q، e و # یا در قالبهای تطبیق الگو مانند `${name#pattern}' رخ میدهند گزارش میشوند. بدون این پرچم، خطاها در سکوت نادیده گرفته میشوند.
- z
- نتیجهٔ بسط را با استفاده از تجزیهٔ شل به کلمات تقسیم میکند تا کلمات را بیابد، یعنی هرگونه نقلقول در مقدار را لحاظ میکند. با کامنتها برخورد ویژهای نمیشود و مانند رشتههای معمولی در نظر گرفته میشوند، شبیه به پوستههای تعاملی که در آنها گزینهٔ INTERACTIVE_COMMENTS تنظیم نشده است (با این حال، برای گزینههای مربوط به این مورد به پرچم Z در زیر نگاه کنید)
توجه داشته باشید که این کار بسیار دیر انجام میشود، حتی دیرتر از پرچم `(s)'. بنابراین برای دسترسی به تککلمات در نتیجه، از بسطهای تودرتو مانند `${${(z)foo}[2]}' استفاده کنید. به همین ترتیب، برای حذف نقلقولها در کلمات حاصل از `${(Q)${(z)foo}}' استفاده کنید.
- 0
- نتیجهٔ بسط را بر اساس بایتهای تهی (null bytes) تقسیم میکند. این میانبُری برای `ps:\0:' است.
پرچمهای زیر (به جز p) با یک یا چند آرگومان همانطور که نشان داده شده است دنبال میشوند. هر کاراکتری، یا جفتهای متناظر `(...)'، `{...}'، `[...]' یا `<...>' میتوانند به جای دونقطه به عنوان جداکننده استفاده شوند، اما توجه داشته باشید که هنگامی که یک پرچم بیش از یک آرگومان میگیرد، یک جفت جداکنندهٔ متناظر باید هر آرگومان را احاطه کند.
- p
- توالیهای گریز یکسانی با دستور توکارِ print را در آرگومانهای رشتهایِ هر یک از پرچمهای توصیفشده در زیر که به دنبال این آرگومان میآیند، شناسایی میکند.
همچنین با این گزینه، آرگومانهای رشتهای میتوانند به صورت $var باشند که در این حالت مقدار متغیر جایگزین میشود. توجه داشته باشید که این قالب سختگیرانه است؛ آرگومان رشتهای دستخوش بسط عمومی پارامتر نمیشود.
برای مثال،
sep=:
val=a:b:c
print ${(ps.$sep.)val}
متغیر را بر اساس : تقسیم میکند. ~ رشتههایی که توسط هر یک از پرچمهای زیر در بسط درج میشوند، بهصورت الگو تلقی خواهند شد. این امر برای آرگومانهای رشتهای پرچمهایی که پس از ~ در همان مجموعه پرانتز میآیند اعمال میشود. این را با ~ در خارج از پرانتز مقایسه کنید که کل رشته جایگزینشده را وادار میکند تا بهعنوان الگو در نظر گرفته شود. بنابراین، به عنوان مثال،
[[ "?" = ${(~j.|.)array} ]]
`|' را به عنوان الگو تلقی کرده و اگر و تنها اگر $array شامل رشته `?' به عنوان یک عنصر باشد با موفقیت پایان مییابد. پرچم ~ را میتوان برای تغییر وضعیت این رفتار تکرار کرد؛ تأثیر آن تنها تا پایان گروه داخل پرانتز باقی میماند.
- j:string:
- واژههای آرایهها را با استفاده از string به عنوان جداکننده به یکدیگر متصل میکند. توجه داشته باشید که این عمل پیش از تفکیک فیلدها توسط پرچم s:string: یا گزینه SH_WORD_SPLIT رخ میدهد.
- l:expr::string1::string2:
- واژههای حاصل را از سمت چپ پدگذاری میکند. هر واژه در صورت نیاز کوتاه شده و در فیلدی به پهنای expr نویسه قرار میگیرد.
آرگومانهای :string1: و :string2: اختیاری هستند؛ هیچکدام، اولی، یا هر دو میتوانند داده شوند. توجه داشته باشید که باید برای هر سه آرگومان از جفت جداکنندههای یکسانی استفاده شود. فضای سمت چپ با string1 (به تعداد دفعات لازم تکرار میشود) یا اگر string1 داده نشده باشد با فاصله پر خواهد شد. اگر هر دو string1 و string2 داده شوند، string2 پیش از آنکه string1 برای تولید هرگونه پدگذاری باقیمانده به کار رود، یک بار مستقیماً در سمت چپ هر واژه درج میشود (در صورت لزوم کوتاه میشود).
اگر هر یک از string1 یا string2 وجود داشته باشد اما خالی باشد، یعنی در آن نقطه دو جداکننده کنار هم باشند، نویسه نخست $IFS به جای آن استفاده میشود.
اگر گزینه MULTIBYTE فعال باشد، پرچم m نیز میتواند داده شود، که در این صورت از پهناها برای محاسبه پدگذاری استفاده خواهد شد؛ در غیر این صورت با تکتک نویسههای چندبایتی به عنوان اشغالکننده یک واحد پهنا برخورد میشود.
اگر گزینه MULTIBYTE فعال نباشد، با هر بایت در رشته به عنوان اشغالکننده یک واحد پهنا برخورد میشود.
همواره فرض میشود که نویسههای کنترلی دارای پهنای یک واحد هستند؛ این امر اجازه میدهد از این سازوکار برای تولید تکرارهای نویسههای کنترلی استفاده شود.
- m
- تنها همراه با یکی از پرچمهای l یا r یا با عملگر طول # هنگامی که گزینه MULTIBYTE فعال باشد، مفید است. از پهنای نویسه گزارششده توسط سیستم برای محاسبه مقدار فضایی که از رشته اشغال میکند یا طول کلی رشته استفاده میکند. اکثر نویسههای قابل چاپ پهنایی معادل یک واحد دارند، با این حال برخی از مجموعهنویسههای آسیایی و برخی جلوههای ویژه از نویسههای عریضتر استفاده میکنند؛ نویسههای ترکیبی پهنای صفر دارند. نویسههای غیرقابلچاپ به طور دلخواه با پهنای صفر شمارش میشوند؛ اینکه در واقعیت چگونه نمایش داده خواهند شد، متفاوت خواهد بود.
اگر m تکرار شود، نویسه یا صفر شمرده میشود (اگر پهنای صفر داشته باشد)، یا یک. برای رشتههای نویسه قابل چاپ، این کار اثر شمارش تعداد گلیفها (نویسههای به ظاهر مجزا) را دارد، به جز مواردی که نویسههای ترکیبی خود پهنای غیرصفر داشته باشند (که در برخی الفباها صادق است).
- r:expr::string1::string2:
- مانند l، اما واژهها را از سمت راست پدگذاری کرده و string2 را بلافاصله در سمت راست رشتهای که باید پدگذاری شود درج میکند.
پدگذاری چپ و راست میتوانند همراه با هم استفاده شوند. در این حالت راهبرد این است که پدگذاری چپ روی نیمه اول پهنای هر یک از واژههای حاصل و پدگذاری راست روی نیمه دوم اعمال شود. اگر رشتهای که باید پدگذاری شود پهنای فرد داشته باشد، پدگذاری اضافی در سمت چپ اعمال میشود.
- s:string:
- تفکیک فیلدها را در جداکننده string اجباری میکند. توجه داشته باشید که یک string با دو یا چند نویسه بدان معناست که همه آنها باید پشت سر هم مطابقت داشته باشند؛ این با نحوه برخورد با دو یا چند نویسه در پارامتر IFS متفاوت است. همچنین پرچم = و گزینه SH_WORD_SPLIT را ببینید. یک رشته خالی نیز میتواند داده شود که در این صورت هر نویسه یک عنصر مجزا خواهد بود.
به دلایل تاریخی، رفتار معمول مبنی بر حفظ عناصر خالی آرایه در درون نقلقولهای دوگانه برای آرایههای تولیدشده با تفکیک غیرفعال شده است؛ بنابراین دستور زیر:
line="one::three"
print -l "${(s.:.)line}"
دو خط خروجی برای one و three تولید میکند و فیلد خالی را نادیده میگیرد. برای لغو این رفتار، پرچم `(@)' را نیز مشخص کنید، یعنی "${(@s.:.)line}".
- Z:opts:
- همانند z است اما ترکیبی از حروف گزینهها را بین یک جفت نویسه جداکننده بعدی میگیرد. بدون هیچ گزینهای، اثر آن با z یکسان است. گزینههای زیر در دسترس هستند:
- (Z+c+)
- باعث میشود کامنتها به صورت یک رشته تجزیه شده و حفظ شوند؛ هر فیلدی در آرایه حاصل که با یک نویسه کامنت نقلقولنشده آغاز شود، یک کامنت است.
- (Z+C+)
- باعث تجزیه و حذف کامنتها میشود. قاعده برای کامنتها استاندارد است: هر چیزی میان کلمهای که با نویسه سوم $HISTCHARS (پیشفرض #) آغاز شود تا خط جدید بعدی، یک کامنت است.
- (Z+n+)
- باعث میشود با خطهای جدیدِ نقلقولنشده مانند نویسه فاصله خالی معمولی رفتار شود، در غیر این صورت با آنها به گونهای رفتار میشود که گویی جداکنندههای کد شل هستند و به نقطهویرگول تبدیل میشوند.
گزینهها درون همان مجموعه از جداکنندهها ترکیب میشوند، مانند (Z+Cn+).
- _:flags:
- پرچم زیرخط (_) برای استفاده در آینده رزرو شده است. تا این بازنگری از zsh، هیچ flags معتبری وجود ندارد؛ هر چیزی به دنبال یک زیرخط، به جز یک جفت جداکننده خالی، به عنوان خطا در نظر گرفته میشود و خود پرچم هیچ اثری ندارد.
پرچمهای زیر با ساختارهای ${...#...} یا ${...%...} معنادار هستند. پرچمهای S، I و * همچنین میتوانند با ساختارهای ${.../...} استفاده شوند.
- S
- همراه با # یا ##، به دنبال تطابقی میگردد که در نزدیکترین نقطه به آغاز رشته شروع شود (یک `تطابق زیررشته'). از میان تمام تطابقها در یک موقعیت مشخص، # کوتاهترین و ## بلندترین را برمیگزیند:
% str="aXbXc"
% echo ${(S)str#X*}
abXc
% echo ${(S)str##X*}
a
%
همراه با % یا %%، به دنبال تطابقی میگردد که در نزدیکترین نقطه به پایان رشته شروع شود:
% str="aXbXc"
% echo ${(S)str%X*}
aXbc
% echo ${(S)str%%X*}
aXb
%
(توجه داشته
باشید که
برخلاف
آنچه ممکن
است انتظار
رود، % و %%
تطابقی را
که به
انتهای
رشته
نزدیکتر
باشد جستجو
نمیکنند.)
هنگام جایگزینی از طریق ${.../...} یا ${...//...}، تطابق غیرحریصانه (non-greedy) را مشخص میکند؛ به این معنی که کوتاهترین تطابق باید به جای طولانیترین تطابق جایگزین شود:
% str="abab"
% echo ${str/*b/_}
_
% echo ${(S)str/*b/_}
_ab
%
- I:expr:
- جستجوی exprاُمین تطابق (که در آن expr به یک عدد ارزیابی میشود). این حالت فقط هنگام جستجو برای زیررشتهها اعمال میشود، چه با پرچم S، یا با ${.../...} (تنها exprاُمین تطابق جایگزین میشود) یا با ${...//...} (تمامی تطابقها از exprاُمین به بعد جایگزین میشوند). حالت پیشفرض، انتخاب اولین تطابق است.
exprاُمین تطابق به گونهای شمارش میشود که از هر موقعیت شروع در رشته یک یا صفر تطابق وجود داشته باشد، اگرچه برای جایگزینی سراسری، تطابقهایی که با جایگزینیهای قبلی همپوشانی دارند نادیده گرفته میشوند. در شکلهای ${...%...} و ${...%%...}، با افزایش اندیس، موقعیت شروع تطابق از انتها به سمت عقب حرکت میکند، در حالی که در سایر شکلها از ابتدا به سمت جلو حرکت میکند.
از این رو با رشتهٔ
which switch is the right switch for Ipswich?
- *
- فعالسازی EXTENDED_GLOB برای جایگزینی از طریق ${.../...} یا ${...//...}. توجه داشته باشید که `**' ویژگی extendedglob را غیرفعال نمیکند.
- B
- گنجاندن اندیس ابتدای تطابق در نتیجه.
- E
- گنجاندن اندیس یک نویسه پس از پایان تطابق در نتیجه (توجه داشته باشید که این موضوع با سایر کاربردهای اندیس پارامتر ناهماهنگ است).
- M
- گنجاندن بخش تطبیقیافته در نتیجه.
- N
- گنجاندن طول تطابق در نتیجه.
- R
- گنجاندن بخش تطبیقنیافته در نتیجه (باقیمانده یا Rest).
قوانین (Rules)
در اینجا خلاصهای از قوانین جایگزینی آورده شده است؛ این بخش فرض میکند که آکولادها در اطراف جایگزینی وجود دارند، یعنی ${...}. چند مثال خاص در ادامه آورده شده است. توجه داشته باشید که گروه توسعه Zsh هیچ مسئولیتی در قبال هرگونه آسیب مغزی که ممکن است هنگام خواندن قوانین زیر رخ دهد نمیپذیرد.
- 1. جایگزینی تودرتو
- اگر چندین شکل تودرتوی ${...} وجود داشته باشد، جایگزینی از درون به بیرون انجام میشود. در هر سطح، جایگزینی اسکالر یا آرایه بودن مقدار فعلی، قرار داشتن کل جایگزینی درون نقلقول جفت (double quotes)، و اینکه چه پرچمهایی به سطح فعلی جایگزینی ارائه شدهاند را در نظر میگیرد، درست مانند اینکه جایگزینی تودرتو بیرونیترین جایگزینی باشد. پرچمها به جایگزینیهای احاطهکننده منتقل نمیشوند؛ جایگزینی تودرتو بر اساس آنچه توسط پرچمها تعیین شده، و احتمالاً با تنظیم برای نقلقول، یک اسکالر یا یک آرایه بازمیگرداند. تمام مراحل زیر در صورت کاربرد، در تمام سطوح جایگزینی انجام میشوند.
توجه داشته باشید که مگر در صورت وجود پرچم `(P)'، پرچمها و هرگونه اندیس مستقیماً روی مقدار جایگزینی تودرتو اعمال میشوند؛ برای مثال، بسط ${${foo}} دقیقاً رفتاری مشابه ${foo} دارد. هنگامی که پرچم `(P)' در یک جایگزینی تودرتو وجود دارد، سایر قوانین جایگزینی قبل از اینکه مقدار به عنوان یک نام تفسیر شود، روی آن اعمال میشوند، بنابراین ${${(P)foo}} ممکن است با ${(P)foo} متفاوت باشد.
در هر سطح تودرتوی جایگزینی، کلمات جایگزینشده دستخوش تمام اشکال جایگزینی تککلمهای (یعنی نه تولید نام فایل) میشوند، از جمله جایگزینی دستور، بسط حسابی و بسط نام فایل (یعنی ~ و = ابتدایی). بنابراین، برای مثال، ${${:-=cat}:h} به دایرکتوریای بسط مییابد که برنامهٔ cat در آن قرار دارد. (توضیح: جایگزینی داخلی هیچ پارامتری ندارد اما دارای یک مقدار پیشفرض =cat است که با بسط نام فایل به یک مسیر کامل بسط داده میشود؛ سپس جایگزینی بیرونی تغییردهندهٔ :h را اعمال کرده و بخش دایرکتوری مسیر را برمیدارد.)
- 2. پرچمهای داخلی پارامتر
- هرگونه پرچم پارامتر تنظیمشده توسط یکی از دستورات خانوادهٔ typeset، به ویژه گزینههای -L، -R، -Z، -u و -l برای فاصلهگذاری (padding) و بزرگنویسی/کوچکنویسی حروف، مستقیماً روی مقدار پارامتر اعمال میشوند. توجه داشته باشید این پرچمها گزینههای دستور هستند، مانند `typeset -Z'؛ آنها با پرچمهای مورد استفاده در جایگزینیهای پارامتر یکسان نیستند.
در بیرونیترین سطح جایگزینی، پرچم `(P)' (قاعدهٔ 4.) این تبدیلها را نادیده میگیرد و از مقدار تغییرنیافتهٔ پارامتر به عنوان نامی که باید جایگزین شود استفاده میکند. این معمولاً رفتار مورد نظر است، زیرا فاصلهگذاری ممکن است مقدار را از لحاظ ساختاری به عنوان نام پارامتر نامعتبر کند، اما اگر تغییر حروف بزرگ/کوچک مد نظر است، از شکل ${${(P)foo}} (قاعدهٔ 25.) استفاده کنید.
- 3. اندیسگذاری پارامتر
- اگر مقدار یک ارجاع خام پارامتر به همراه یک اندیس باشد، مانند ${var[3]}، اثر اندیسگذاری مستقیماً روی پارامتر اعمال میشود. اندیسها از چپ به راست ارزیابی میشوند؛ اندیسهای بعدی روی مقدار اسکالر یا آرایهای اعمال میشوند که توسط اندیس قبلی حاصل شده است. بنابراین اگر var یک آرایه باشد، ${var[1][2]} دومین نویسه از کلمهٔ اول است، اما ${var[2,4][2]} کل کلمهٔ سوم است (کلمهٔ دوم از محدودهٔ کلمات دو تا چهارِ آرایهٔ اصلی). هر تعداد اندیس میتواند ظاهر شود. پرچمهایی مانند `(k)' و `(v)' که نتیجهٔ اندیسگذاری را تغییر میدهند، اعمال میشوند.
- 4. جایگزینی نام پارامتر
- تنها در بیرونیترین سطح تودرتویی، پرچم `(P)' اعمال میشود. این پرچم با مقدار بهدستآمده تا این لحظه به عنوان یک نام پارامتر (که ممکن است شامل عبارت اندیس باشد) برخورد کرده و آن را با مقدار متناظر جایگزین میکند. اگر پرچم `(P)' در یک جایگزینی تودرتو ظاهر شود، این جایگزینی دیرتر رخ میدهد.
اگر مقدار تا این لحظه نام پارامتری باشد که پرچمهای داخلی دارد (قاعدهٔ 2.)، آن پرچمهای داخلی پس از جایگزینی روی مقدار جدید اعمال میشوند.
- 5. اتصال با نقلقول جفت
- اگر مقدار پس از این فرایند یک آرایه باشد، و جایگزینی درون نقلقول جفت (double quotes) ظاهر شود، و نه پرچم `(@)' و نه عملگر طول `#' در سطح فعلی حاضر نباشند، آنگاه کلمات مقدار با اولین نویسهٔ پارامتر $IFS (بهطور پیشفرض یک فاصله) بین هر کلمه به هم متصل میشوند (آرایههای تککلمهای تغییر نمیکنند). اگر پرچم `(j)' وجود داشته باشد، به جای $IFS برای اتصال استفاده میشود.
- 6. اندیسگذاری تودرتو
- هرگونه اندیس باقیمانده (یعنی مربوط به یک جایگزینی تودرتو) در این مرحله ارزیابی میشود، بر اساس اینکه مقدار یک آرایه است یا یک اسکالر. همانند 3.، چندین اندیس میتوانند ظاهر شوند. توجه داشته باشید که بنابراین ${foo[2,4][2]} معادل ${${foo[2,4]}[2]} و همچنین معادل "${${(@)foo[2,4]}[2]}" است (جایگزینی تودرتو در هر دو مورد یک آرایه بازمیگرداند)، اما معادل "${${foo[2,4]}[2]}" نیست (جایگزینی تودرتو به دلیل نقلقولها یک اسکالر بازمیگرداند).
- 7. تغییردهندهها
- هرگونه تغییردهنده، همانطور که توسط یک `#'، `%'، `/' پایانی (احتمالاً مضاعف) یا مجموعهای از تغییردهندهها به شکل `:...' مشخص شده است (بخش `Modifiers' را در بخش `History Expansion' ببینید)، روی کلمات مقدار در این سطح اعمال میشوند.
- 8. ارزیابی نویسه
- هرگونه پرچم `(#)' اعمال میشود، و نتیجه را تا این مرحله به صورت عددی به عنوان یک نویسه ارزیابی میکند.
- 9. طول
- هرگونه تغییردهندهٔ ابتدایی `#'، یعنی به شکل ${#var}، برای ارزیابی طول عبارت تا این مرحله به کار میرود..TP 10. اتصال اجباری اگر پرچم `(j)' وجود داشته باشد، یا هیچ پرچم `(j)' وجود نداشته باشد اما قرار باشد رشته طبق قاعدهٔ 11. تفکیک شود، و اتصال در قاعدهٔ 5. رخ نداده باشد، هر کلمهای در این مقدار با استفاده از رشتهٔ ارائهشده یا نخستین نویسهٔ $IFS در صورت نبود آن، به یکدیگر متصل میشوند. توجه داشته باشید که پرچم `(F)' به صورت ضمنی رشتهای را برای اتصال به این شیوه فراهم میکند.
- 11. تفکیک سادهٔ کلمات
- اگر یکی از پرچمهای `(s)' یا `(f)' وجود داشته باشد، یا مشخصکنندهٔ `=' حضور داشته باشد (برای نمونه ${=var})، کلمه بر اساس رخدادهای رشتهٔ مشخصشده تفکیک میشود، یا (برای `=' در صورتی که هیچیک از این دو پرچم وجود نداشته باشد) بر اساس هر یک از نویسههای موجود در $IFS تفکیک میگردد.
اگر هیچیک از `(s)'، `(f)' یا `=' داده نشده باشد، اما کلمه درون نقلقول نباشد و گزینهٔ SH_WORD_SPLIT فعال باشد، کلمه بر اساس رخداد هر یک از نویسههای موجود در $IFS تفکیک میشود. توجه داشته باشید که این مرحله نیز در تمام سطوح یک جایگزینی تو در تو انجام میگیرد.
- 12. تغییر بزرگی و کوچکی حروف
- هرگونه تغییر در بزرگی و کوچکی حروف ناشی از یکی از پرچمهای `(L)'، `(U)' یا `(C)' اعمال میشود.
- 13. جایگزینی توالیهای گریز
- نخست هرگونه جایگزینی مربوط به پرچم `(g)' انجام میشود، سپس هرگونه قالببندی به سبک اعلان (prompt) از خانوادهٔ پرچمهای `(%)' اعمال میگردد.
- 14. اعمال نقلقول
- هرگونه نقلقولگذاری یا حذف نقلقول با استفاده از `(q)' و `(Q)' و پرچمهای وابسته اعمال میشود.
- 15. نامگذاری دایرکتوری
- هرگونه جایگزینی نام دایرکتوری با استفاده از پرچم `(D)' اعمال میشود.
- 16. بهبود نمایانی
- هرگونه تغییر برای نمایان ساختن نویسهها با استفاده از پرچم `(V)' اعمال میشود.
- 17. تفکیک واژگانی کلمات
- اگر پرچم '(z)' یا یکی از حالتهای پرچم '(Z)' وجود داشته باشد، کلمه طوری تفکیک میشود که گویی یک خط فرمان پوسته است، به گونهای که علامتهای نقلقول و دیگر فرانوسهها برای تصمیمگیری در مورد این که چه چیزی یک کلمه را تشکیل میدهد استفاده میشوند. توجه داشته باشید که این شکل از تفکیک، کاملاً متمایز از موردی است که در قاعدهٔ 11. شرح داده شده است: این روش از $IFS استفاده نمیکند و موجب اتصال اجباری نیز نمیشود.
- 18. یکتاسازی
- اگر حاصل یک آرایه باشد و پرچم `(u)' داده شده باشد، عناصر تکراری از آرایه حذف میشوند.
- 19. مرتبسازی
- اگر حاصل همچنان یک آرایه باشد و یکی از پرچمهای `(o)' یا `(O)' وجود داشته باشد، آرایه دوباره مرتب میشود.
- 20. RC_EXPAND_PARAM
- در این مرحله تصمیم گرفته میشود که آیا عناصر آرایهٔ حاصل باید عنصر به عنصر با متن پیرامون ترکیب شوند یا خیر، همانگونه که توسط گزینهٔ RC_EXPAND_PARAM یا پرچم `^' تعیین میشود.
- 21. ارزیابی مجدد
- هر پرچم `(e)' بر روی مقدار اعمال میشود و آن را وادار میسازد تا نه تنها برای جایگزینیهای پارامتر جدید، بلکه برای جایگزینیهای دستوری و محاسباتی نیز مجدداً بازبینی شود.
- 22. پر کردن (Padding)
- هرگونه پر کردن مقدار با استفاده از پرچمهای `(l.fill.)' یا `(r.fill.)' اعمال میشود.
- 23. اتصال معنایی
- در زمینههایی که معناشناسی بسط نیازمند حاصل شدن یک کلمهٔ منفرد است، تمام کلمات با قرار گرفتن نخستین نویسهٔ IFS در میانشان، مجدداً به هم متصل میشوند. بنابراین در `${(P)${(f)lines}}' مقدار ${lines} در خطوط جدید تفکیک میشود، اما سپس پیش از اعمال پرچم `(P)' باید دوباره به هم متصل گردد.
اگر به یک کلمهٔ منفرد نیازی نباشد، این قاعده نادیده گرفته میشود.
- 24. حذف آرگومانهای خالی
- اگر جایگزینی درون نقلقول دوتایی قرار نگرفته باشد، هرگونه آرگومان با طول صفر حاصل، خواه از یک متغیر اسکالر یا از یک عنصر آرایه باشد، از فهرست آرگومانهای درجشده در خط فرمان حذف میشود.
دقیقتر بگوییم، این حذف بعداً انجام میگیرد چرا که همین اتفاق برای سایر اشکال جایگزینی نیز رخ میدهد؛ نکتهای که در اینجا باید مد نظر داشت صرفاً این است که این فرایند پس از هر یک از عملیاتهای پارامتری بالا رخ میدهد.
- 25. جایگزینی نام پارامتر تو در تو
- اگر پرچم `(P)' وجود داشته باشد و قاعدهٔ 4. اعمال نشده باشد، با مقدار حاصل تا این مرحله به عنوان نام یک پارامتر (که ممکن است شامل عبارت اندیس باشد) برخورد شده و با مقدار متناظر آن جایگزین میشود، در حالی که پرچمهای داخلی (قاعدهٔ 2.) روی مقدار جدید اعمال میگردند. پرچم f برای تفکیک خطبهخط یک جایگزینی درون نقلقولهای جفتی مفید است. برای نمونه، ${(f)"$(<file)"} محتویات file را چنان جایگزین میکند که هر خط یک عنصر از آرایهٔ حاصل باشد. این را با اثر $(<file) بهتنهایی مقایسه کنید که فایل را بر اساس کلمات تفکیک میکند، یا همان مورد در داخل نقلقولهای جفتی، که تمام محتوای فایل را به یک رشتهٔ واحد تبدیل میکند.
موارد زیر قواعد مربوط به بسطهای تودرتوی پارامتر را نشان میدهد. فرض کنید $foo شامل آرایهٔ (bar baz) است:
- "${(@)${foo}[1]}"
- این مورد نتیجهٔ b را تولید میکند. نخست، جایگزینی درونی "${foo}"، که هیچ پرچم آرایهای (@) ندارد، یک نتیجهٔ تککلمهای "bar baz" تولید میکند. جایگزینی بیرونی "${(@)...[1]}" تشخیص میدهد که این یک مقدار اسکالر است، بنابراین (با وجود پرچم `(@)') اندیس، نخستین نویسه را برمیگزیند.
- "${${(@)foo}[1]}"
- این مورد نتیجهٔ `bar' را تولید میکند. در این حالت، جایگزینی درونی "${(@)foo}" آرایهٔ `(bar baz)' را تولید میکند. جایگزینی بیرونی "${...[1]}" تشخیص میدهد که این یک آرایه است و نخستین کلمه را برمیگزیند. این شبیه به حالت سادهٔ "${foo[1]}" است.
بهعنوان مثالی از قواعد تفکیک و پیوند کلمات، فرض کنید $foo شامل آرایهٔ `(ax1 bx1)' باشد. آنگاه
- ${(s/x/)foo}
- کلمات `a'، `1 b' و `1' را تولید میکند.
- ${(j/x/s/x/)foo}
- مقادیر `a'، `1'، `b' و `1' را تولید میکند.
- ${(s/x/)foo%%1*}
- مقادیر `a' و ` b' را تولید میکند (به فاصلهٔ اضافی دقت کنید). از آنجا که جایگزینی پیش از پیوند دادن یا تفکیک رخ میدهد، این عملیات ابتدا آرایهٔ تغییریافتهٔ (ax bx) را تولید میکند، که برای ساخت "ax bx" پیوند داده میشود و سپس تفکیک میگردد تا `a'، ` b' و `' را بدهد. رشتهٔ خالی پایانی سپس حذف خواهد شد، چرا که درون نقلقولهای جفتی نیست.
جایگزینی دستور (COMMAND SUBSTITUTION)
دستوری که درون پرانتز و پس از یک علامت دلار قرار گیرد، مانند `$(...)'، یا با علامت تکیهصدا نقل شده باشد، مانند ``...`'، با خروجی استاندارد خود جایگزین میشود، در حالی که خطهای جدید پایانی حذف میشوند. اگر این جایگزینی درون نقلقولهای جفتی قرار نگرفته باشد، خروجی با استفاده از پارامتر IFS به کلمات تفکیک میشود.
جایگزینی `$(cat foo)' میتواند با عبارت سریعترِ `$(<foo)' جایگزین شود. در این حالت foo تحت بسطهای تککلمهای پوسته (بسط پارامتر، جایگزینی دستور و بسط محاسباتی) قرار میگیرد، اما تولید نام فایل روی آن اعمال نمیشود.
اگر گزینهٔ GLOB_SUBST تنظیم شده باشد، نتیجهٔ هر جایگزینی دستورِ بدون نقلقول، از جمله شکل ویژهای که پیشتر اشاره شد، واجد شرایط تولید نام فایل خواهد بود.
بسط محاسباتی (ARITHMETIC EXPANSION)
رشتهای به شکل `$[exp]' یا `$((exp))' با مقدار عبارت محاسباتی exp جایگزین میشود. exp پیش از ارزیابی، تحت بسط پارامتر، جایگزینی دستور و بسط محاسباتی قرار میگیرد. بخش `Arithmetic Evaluation' را ببینید.
بسط آکولاد (BRACE EXPANSION)
رشتهای به شکل `foo{xx,yy,zz}bar' به کلمات مجزای `fooxxbar'، `fooyybar' و `foozzbar' بسط مییابد. ترتیب چپبهراست حفظ میشود. این ساختار میتواند تودرتو باشد. میتوان کاماها را نقلقولگذاری کرد تا بهصورت لفظی درون کلمه گنجانده شوند.
عبارتی به شکل `{n1..n2}'، که در آن n1 و n2 اعدادی صحیح هستند، به تمام اعداد بین n1 و n2 شامل خود آنها بسط مییابد. اگر هر یک از اعداد با یک صفر آغاز شود، تمام اعداد حاصل با صفرهای پیشین تا حداقل آن پهنا پر (pad) میشوند، اما برای اعداد منفی نویسهٔ - نیز در پهنا به حساب میآید. اگر اعداد به ترتیب کاهشی باشند، دنبالهٔ حاصل نیز به ترتیب کاهشی خواهد بود.
عبارتی به شکل `{n1..n2..n3}'، که در آن n1، n2 و n3 اعدادی صحیح هستند، همانند بالا بسط مییابد، اما تنها هر n3-امین عدد با شروع از n1 خروجی داده میشود. اگر n3 منفی باشد، اعداد به ترتیب معکوس خارج میشوند؛ این حالت در صورتی که گام n3 بازه را بهطور مساوی بخشپذیر نکند، کمی با جابهجایی سادهٔ n1 و n2 تفاوت دارد. پر کردن با صفر را میتوان در هر یک از این سه عدد مشخص کرد؛ تعیین آن در عدد سوم میتواند برای نمونه جهت پر کردن `{-99..100..01}' مفید باشد، که مشخص کردن آن با گذاشتن یک 0 روی هر یک از دو عدد نخست امکانپذیر نیست (یعنی پر کردن تا دو نویسه).
عبارتی به شکل `{c1..c2}'، که در آن c1 و c2 نویسههای منفرد هستند (که ممکن است نویسههای چندبایتی باشند)، به هر نویسه در بازهٔ c1 تا c2 در هر توالی نویسهای که بهطور داخلی استفاده میشود، بسط مییابد. برای نویسههایی با نقطه کد زیر ۱۲۸، این همان US ASCII است (که تنها حالتی است که بیشتر کاربران به آن نیاز خواهند داشت). اگر هر نویسهٔ بینابینی غیرقابلچاپ باشد، از نقلقولگذاری مناسب برای قابلچاپ کردن آن استفاده میشود. اگر توالی نویسهها معکوس باشد، خروجی به ترتیب معکوس خواهد بود، برای نمونه `{d..a}' بهصورت `d c b a' جایگزین میشود.
اگر عبارت آکولادی با هیچیک از شکلهای بالا مطابقت نداشته باشد، دستنخورده باقی میماند، مگر اینکه گزینهٔ BRACE_CCL (مخفف `brace character class') تنظیم شده باشد. در آن صورت، به فهرستی از نویسههای منفردِ بین آکولادها که بر اساس ترتیب نویسهها در مجموعه نویسههای ASCII مرتب شدهاند بسط مییابد (نویسههای چندبایتی در حال حاضر پشتیبانی نمیشوند). نحو آن شبیه به یک عبارت [...] در تولید نام فایل است: با `-' برای مشخص کردن بازهای از نویسهها بهطور ویژه رفتار میشود، اما `^' یا `!' بهعنوان نخستین نویسه بهطور عادی رفتار خواهد شد. برای نمونه، `{abcdef0-9}' به ۱۶ کلمهٔ 0 1 2 3 4 5 6 7 8 9 a b c d e f بسط مییابد.
توجه داشته باشید که بسط آکولاد بخشی از تولید نام فایل (globbing) نیست؛ عبارتی مانند */{foo,bar} پیش از انجام تولید نام فایل به دو کلمهٔ جداگانهٔ */foo و */bar تفکیک میشود. بهویژه، توجه داشته باشید که اگر هر یک از دو عبارت مطابقت نداشته باشد، احتمال ایجاد خطای `no match' وجود دارد؛ این را باید با */(foo|bar) مقایسه کرد، که بهعنوان یک الگوی واحد تلقی میشود اما در غیر این صورت اثرات مشابهی دارد.
برای ترکیب بسط آکولاد با بسط آرایه، شکل ${^spec} توصیفشده در بخش `Parameter Expansion' در بالا را ببینید. هر کلمه بررسی میشود تا مشخص شود آیا با یک «~» بدون نقلقول آغاز میشود یا خیر. اگر چنین باشد، کلمه تا یک «/»، یا تا انتهای کلمه در صورت نبود «/»، بررسی میشود تا مشخص گردد آیا میتواند با یکی از روشهای شرحدادهشده در اینجا جایگزین شود یا خیر. در این صورت، «~» و بخش بررسیشده با مقدار جایگزین مناسب تعویض میشوند.
یک «~» به تنهایی با مقدار $HOME جایگزین میشود. یک «~» که پس از آن «+» یا «-» بیاید، به ترتیب با دایرکتوری کاری فعلی یا قبلی جایگزین میگردد.
یک «~» که پس از آن یک عدد بیاید، با دایرکتوری موجود در آن جایگاه از پشته دایرکتوری (directory stack) جایگزین میشود. «~0» معادل «~+» است، و «~1» بالای پشته است. «~+» به همراه یک عدد با دایرکتوری در آن جایگاه از پشته دایرکتوری جایگزین میشود. «~+0» معادل «~+» است، و «~+1» بالای پشته است. «~-» به همراه یک عدد با دایرکتوری به همان تعداد جایگاه از پایین پشته جایگزین میشود. «~-0» پایین پشته است. گزینه PUSHD_MINUS تأثیر «~+» و «~-» را در حالتی که پس از آنها عدد بیاید، جابجا میکند.
دایرکتوریهای نامگذاریشده پویا (Dynamic named directories)
اگر تابع zsh_directory_name وجود داشته باشد، یا متغیر پوسته zsh_directory_name_functions موجود بوده و شامل آرایهای از نامهای توابع باشد، آنگاه این توابع برای پیادهسازی نامگذاری پویای دایرکتوری به کار میروند. توابع به ترتیب امتحان میشوند تا زمانی که یکی از آنها وضعیت صفر بازگرداند؛ بنابراین مهم است که توابع بررسی کنند آیا میتوانند مورد مربوطه را پردازش کنند و وضعیت مناسب بازگردانند یا خیر.
یک «~» که به دنبال آن رشته namstr در قلابهای باز و بسته بدون نقلقول قرار گیرد، به صورت ویژه به عنوان نام پویای دایرکتوری در نظر گرفته میشود. توجه داشته باشید که نخستین قلاب بسته بدون نقلقول همیشه به namstr پایان میدهد. به تابع پوسته دو آرگومان ارسال میشود: رشته n (برای name) و namstr. این تابع یا باید آرایه reply را به یک تکعنصر که دایرکتوری متناظر با نام است تنظیم کند و وضعیت صفر بازگرداند (اجرای یک انتساب به عنوان آخرین دستور معمولاً کافی است)، یا باید وضعیتی غیرصفر بازگرداند. در حالت اول، عنصر reply به عنوان دایرکتوری استفاده میشود؛ در حالت دوم، جایگزینی ناموفق تلقی میگردد. اگر تمام توابع شکست بخورند و گزینه NOMATCH تنظیم شده باشد، خطایی رخ خواهد داد.
توابعی که در بالا تعریف شدهاند همچنین برای بررسی این که آیا میتوان یک دایرکتوری را به یک نام تبدیل کرد یا خیر استفاده میشوند؛ برای نمونه هنگام چاپ پشته دایرکتوری یا هنگام گسترش %~ در خط اعلان (prompts). در این حالت به هر تابع دو آرگومان ارسال میشود: رشته d (برای directory) و نامزد نامگذاری پویا. تابع در صورتی که دایرکتوری نتواند توسط آن نامگذاری شود باید وضعیتی غیرصفر بازگرداند، یا این که باید آرایه reply را به دو عنصر مقداردهی کند: اولی نام پویای دایرکتوری است (همانطور که در داخل «~[...]» ظاهر میشود)، و دومی طول پیشوندِ دایرکتوری است که باید جایگزین شود. برای نمونه، اگر دایرکتوری آزمایشی /home/myname/src/zsh باشد و نام پویا برای /home/myname/src (که ۱۶ نویسه دارد) s باشد، آنگاه تابع تنظیم میکند:
reply=(s 16)
نام دایرکتوری بازگرداندهشده بدین صورت، با نامهای ایستای احتمالی برای بخشهایی از مسیر دایرکتوری (همانطور که در زیر شرح داده شده) مقایسه میشود؛ در صورتی استفاده میشود که طول پیشوند تطبیقیافته (۱۶ در این مثال) از طول تطبیقیافته توسط هر نام ایستایی بلندتر باشد.
الزامی نیست که یک تابع هر دو فراخوانی n و d را پیادهسازی کند؛ برای نمونه، ممکن است مناسب باشد که برخی اشکال پویای گسترش به نامها کوتاه نشوند. در این حالت هر فراخوانی با نخستین آرگومان d باید باعث بازگرداندن یک وضعیت غیرصفر شود.
سامانه تکمیل خودکار (completion)، عبارت «zsh_directory_name c» و سپس فراخوانیهای مشابه برای عناصر آرایه zsh_directory_name_functions (در صورت وجود) را اجرا میکند تا نامهای پویا برای دایرکتوریها را تکمیل نماید. کد مربوط به این کار باید مانند هر تابع تکمیل دیگری باشد که در zshcompsys(1) شرح داده شده است.
به عنوان یک نمونه کاربردی، در اینجا تابعی آورده شده است که هر نام پویای شروعشونده با رشته p: را به دایرکتوریهای زیر /home/pws/perforce گسترش میدهد. در این مورد ساده، یک نام ایستا برای دایرکتوری نیز به همان اندازه کارآمد خواهد بود.
zsh_directory_name() {
emulate -L zsh
setopt extendedglob
local -a match mbegin mend
if [[ $1 = d ]]; then
# turn the directory into a name
if [[ $2 = (#b)(/home/pws/perforce/)([^/]##)* ]]; then
typeset -ga reply
reply=(p:$match[2] $(( ${#match[1]} + ${#match[2]} )) )
else
return 1
fi
elif [[ $1 = n ]]; then
# turn the name into a directory
[[ $2 != (#b)p:(?*) ]] && return 1
typeset -ga reply
reply=(/home/pws/perforce/$match[1])
elif [[ $1 = c ]]; then
# complete names
local expl
local -a dirs
dirs=(/home/pws/perforce/*(/:t))
dirs=(p:${^dirs})
_wanted dynamic-dirs expl 'dynamic directory' compadd -S\] -a dirs
return
else
return 1
fi
return 0
}
همچنین تعریف نامهای دایرکتوری با استفاده از گزینهٔ -d در دستور توکار hash امکانپذیر است.
هنگامی که شل مسیری را چاپ میکند (برای نمونه، هنگام بسط %~ در اعلانات خط فرمان یا هنگام چاپ پشتهٔ دایرکتوری)، مسیر بررسی میشود تا مشخص شود آیا یک دایرکتوری نامگذاریشده به عنوان پیشوند آن وجود دارد یا خیر. در این صورت، بخش پیشوند با یک `~' به همراه نام دایرکتوری جایگزین میشود. از بین دو روش ارجاع به دایرکتوری، روش کوتاهتر استفاده میشود، یعنی یا نام دایرکتوری یا مسیر کامل؛ و در صورتی که طول یکسانی داشته باشند، نام به کار میرود. پارامترهای $PWD و $OLDPWD هرگز به این شیوه خلاصه نمیشوند.
بسط `=' (`=' expansion)
اگر کلمهای با یک `=' بدون نقلقول آغاز شود و گزینهٔ EQUALS تنظیم شده باشد، باقیماندهٔ کلمه به عنوان نام یک دستور در نظر گرفته میشود. اگر دستوری با آن نام وجود داشته باشد، کلمه با نام مسیر کامل آن دستور جایگزین میشود.
نکات (Notes)
بسط نام فایل در سمت راست یک انتساب پارامتر انجام میشود، از جمله مواردی که پس از دستورهای خانوادهٔ typeset ظاهر میشوند. در این حالت، سمت راست مانند پارامتر PATH به صورت فهرستی جداشده با دونقطه در نظر گرفته میشود، به طوری که یک `~' یا یک `=' پس از یک `:' واجد شرایط بسط است. تمام این رفتارها را میتوان با نقلقول کردن `~'، `='، یا کل عبارت (نه صرفاً دونقطه) غیرفعال کرد؛ گزینهٔ EQUALS نیز رعایت میشود.
اگر گزینهٔ MAGIC_EQUAL_SUBST تنظیم شده باشد، هر آرگومان بدون نقلقول شل به شکل `identifier=expression' واجد شرایط بسط فایل به صورتی که در بند پیشین شرح داده شد میشود. نقلقول کردن نخستین `=' نیز مانع از این کار میشود.
تولید نام فایل (FILENAME GENERATION)
اگر کلمهای حاوی یک نمونهٔ بدون نقلقول از یکی از نویسههای `*'، `('، `|'، `<'، `['، یا `?' باشد، به عنوان الگویی برای تولید نام فایل در نظر گرفته میشود، مگر اینکه گزینهٔ GLOB غیرفعال باشد. اگر گزینهٔ EXTENDED_GLOB تنظیم شده باشد، نویسههای `^' و `#' نیز نمایانگر الگو هستند؛ در غیر این صورت رفتار ویژهای توسط شل با آنها صورت نمیگیرد.
کلمه با فهرستی از نامهای فایل مرتبشده که با الگو مطابقت دارند جایگزین میشود. اگر هیچ الگوی تطبیقیافتهای یافت نشود، شل یک پیام خطا صادر میکند، مگر اینکه گزینهٔ NULL_GLOB تنظیم شده باشد، که در این صورت کلمه حذف میشود؛ یا مگر اینکه گزینهٔ NOMATCH غیرفعال باشد، که در این صورت کلمه بدون تغییر رها میشود.
در تولید نام فایل، نویسهٔ `/' باید به طور صریح مطابقت داده شود؛ همچنین، یک `.' در ابتدای یک الگو یا پس از یک `/' باید به طور صریح مطابقت داده شود، مگر اینکه گزینهٔ GLOB_DOTS تنظیم شده باشد. هیچ الگوی تولید نام فایلی با فایلهای `.' یا `..' مطابقت ندارد. در سایر نمونههای تطبیق الگو، با `/' و `.' به طور ویژه رفتار نمیشود.
عملگرهای گلوب (Glob Operators)
- *
- با هر رشتهای، شامل رشتهٔ تهی (null)، مطابقت دارد.
- ?
- با هر تکنویسهای مطابقت دارد.
- [...]
- با هر یک از نویسههای محصور مطابقت دارد. بازههایی از نویسهها را میتوان با جدا کردن دو نویسه به وسیلهٔ یک `-' مشخص کرد. یک `-' یا `]' را میتوان با قرار دادن آن به عنوان نخستین نویسه در فهرست مطابقت داد. همچنین چندین ردهٔ نامگذاریشده از نویسهها به شکل `[:name:]' با معانی زیر وجود دارند. مجموعهٔ نخست از ماکروهای ارائهشده توسط سیستمعامل برای آزمایش ترکیبهای نویسهٔ دادهشده استفاده میکند، شامل هرگونه تغییرات ناشی از تنظیمات زبان محلی؛ به ctype(3) مراجعه کنید:
- [:alnum:]
- نویسه الفبایی-عددی است
- [:alpha:]
- نویسه الفبایی (حرفی) است
- [:ascii:]
- نویسه ۷-بیتی است، یعنی یک نویسهٔ تکبایتی است که بیت بالایی آن تنظیم نشده است.
- [:blank:]
- نویسه یک نویسهٔ خالی (blank) است
- [:cntrl:]
- نویسه یک نویسهٔ کنترلی است
- [:digit:]
- نویسه یک رقم دهدهی است
- [:graph:]
- نویسه یک نویسهٔ قابلچاپ غیر از نویسهٔ فاصله است
- [:lower:]
- نویسه یک حرف کوچک است
- [:print:]
- نویسه قابلچاپ است
- [:punct:]
- نویسه قابلچاپ است اما نه الفبایی-عددی است و نه فاصله
- [:space:]
- نویسه فاصلهٔ سفید (whitespace) است
- [:upper:]
- نویسه یک حرف بزرگ است
- [:xdigit:]
- نویسه یک رقم هگزادسیمال است
مجموعهٔ دیگری از ردههای نامگذاریشده به طور داخلی توسط شل مدیریت میشود و به محلیسازی (locale) حساس نیست:
- [:IDENT:]
- نویسه مجاز است بخشی از یک شناسهٔ شل را تشکیل دهد، مانند یک نام پارامتر؛ این آزمایش از گزینهٔ POSIX_IDENTIFIERS پیروی میکند
- [:IFS:]
- نویسه به عنوان جداکنندهٔ فیلد ورودی استفاده میشود، یعنی در پارامتر IFS موجود است
- [:IFSSPACE:]
- نویسه یک نویسهٔ فاصلهٔ سفید IFS است؛ به مستندات مربوط به IFS در صفحهٔ راهنمای zshparam(1) مراجعه کنید.
- [:INCOMPLETE:]
- با بایتی مطابقت دارد که یک نویسهٔ چندبایتی ناقص را شروع میکند. توجه داشته باشید که ممکن است دنبالهای بیش از یک بایت وجود داشته باشد که در کنار هم پیشوند یک نویسهٔ چندبایتی را تشکیل دهند. برای آزمایش یک دنباله بایت بالقوه ناقص، از الگوی `[[:INCOMPLETE:]]*' استفاده کنید. این الگو هرگز با دنبالهای که با یک نویسهٔ چندبایتی معتبر شروع شود مطابقت نخواهد داشت.
- [:INVALID:]
- با بایتی مطابقت دارد که یک نویسهٔ چندبایتی معتبر را شروع نمیکند. توجه داشته باشید که این ممکن است یک بایت ادامه از یک نویسهٔ چندبایتی ناقص باشد، چرا که هر بخشی از یک رشتهٔ چندبایتی متشکل از نویسههای چندبایتی نامعتبر و ناقص، به عنوان تکبایت در نظر گرفته میشود.
- [:WORD:]
- با نویسه به عنوان بخشی از یک کلمه رفتار میشود؛ این آزمایش به مقدار پارامتر WORDCHARS حساس است
توجه داشته باشید که قلابها (کروشهها) علاوه بر کروشههایی هستند که کل مجموعهٔ نویسهها را در بر میگیرند، بنابراین برای آزمایش یک نویسهٔ الفبایی-عددی منفرد به `[[:alnum:]]' نیاز دارید. مجموعههای نویسهٔ نامگذاریشده را میتوان در کنار انواع دیگر به کار برد، مانند `[[:alpha:]0-9]'.
[^...]
- [!...]
- مشابه [...]، با این تفاوت که با هر نویسهای که در مجموعهٔ دادهشده نباشد مطابقت میکند.
- <[x]-[y]>
- با هر عددی در بازهٔ x تا y، شامل خود آنها، مطابقت میکند. هر یک از این دو عدد را میتوان حذف کرد تا بازه بیانتها (باز) شود؛ بنابراین `<->' با هر عددی مطابقت مییابد. برای تطبیق تکرقمها، شکل [...] کارآمدتر است.
هنگام استفاده از دیگر نویسههای عام (wildcards) در مجاورت الگوهایی با این ساختار دقت کنید؛ برای مثال، <0-9>* در عمل با هر عددی در ابتدای رشته مطابقت خواهد کرد، چرا که `<0-9>' با رقم اول تطابق یافته و `*' با سایر ارقام مطابقت مییابد. این دامی برای افراد ناوارد است، اما در واقع نتیجهٔ اجتنابناپذیر این قاعده است که طولانیترین تطابق ممکن همواره پیروز میشود. در عوض میتوان از عبارتهایی نظیر `<0-9>[^[:digit:]]*' استفاده کرد.
- (...)
- با الگوی محصورشده مطابقت میکند. از این ساختار برای گروهبندی استفاده میشود. اگر گزینهٔ KSH_GLOB تنظیم شده باشد، قرار گرفتن مستقیم نویسههای `@'، `*'، `+'، `?' یا `!' درست پیش از `(' به صورت ویژه مدیریت میشود، همانطور که در ادامه توضیح داده شده است. گزینهٔ SH_GLOB از استفاده از پرانتزهای تنها به این شکل جلوگیری میکند، هرچند گزینهٔ KSH_GLOB همچنان در دسترس است.
توجه داشته باشید که گروهبندی نمیتواند روی چندین دایرکتوری گسترش یابد: قرار داشتن `/' درون یک گروه یک خطا است (این قاعده فقط برای الگوهای مورد استفاده در تولید نام فایل صدق میکند). یک استثنا وجود دارد: گروهی به شکل (pat/)# که به عنوان یک بخش کامل از مسیر ظاهر شود میتواند با توالیای از دایرکتوریها مطابقت کند. برای مثال، foo/(a*/)#bar با foo/bar، foo/any/bar، foo/any/anyother/bar و غیره مطابقت دارد.
- x|y
- یا با x و یا با y مطابقت میکند. این عملگر تقدم کمتری نسبت به سایر عملگرها دارد. نویسهٔ `|' باید درون پرانتز قرار گیرد تا از تفسیر آن به عنوان خط لوله (pipeline) جلوگیری شود. گزینهها به ترتیب از چپ به راست ارزیابی میشوند.
- ^x
- (نیازمند فعال بودن گزینهٔ EXTENDED_GLOB است.) با هر چیزی به جز الگوی x مطابقت میکند. این عملگر تقدم بالاتری نسبت به `/' دارد، بنابراین `^foo/bar' دایرکتوریهای موجود در `.' به جز `./foo' را به دنبال فایلی به نام `bar' جستجو خواهد کرد.
- x~y
- (نیازمند فعال بودن گزینهٔ EXTENDED_GLOB است.) با هر آنچه که با الگوی x مطابقت داشته باشد اما با y مطابقت نداشته باشد، تطابق مییابد. این عملگر تقدم کمتری نسبت به تمام عملگرها به جز `|' دارد، بنابراین `*/*~foo/bar' تمام فایلهای همهٔ دایرکتوریهای `.' را جستجو کرده و سپس در صورت وجود چنین تطابقی، `foo/bar' را مستثنی میکند. الگوهای چندگانه را میتوان به صورت `foo~bar~baz' مستثنی کرد. در الگوی استثنا (y)، نویسههای `/' و `.' رفتار ویژهای شبیه به کاربرد معمولشان در globbing نخواهند داشت.
- x#
- (نیازمند فعال بودن گزینهٔ EXTENDED_GLOB است.) با صفر یا چند بار تکرار الگوی x مطابقت میکند. این عملگر تقدم بالایی دارد؛ `12#' معادل `1(2#)' است، نه `(12)#'. قرار گرفتن یک `#' نقلقولنشده به دنبال چیزی که قابل تکرار نیست، یک خطا محسوب میشود؛ این شامل یک رشتهٔ خالی، الگویی که پیشتر به دنبال آن `##' آمده است، یا پرانتزها هنگامی که بخشی از الگوی KSH_GLOB باشند (به عنوان مثال، `!(foo)#' نامعتبر است و باید با `*(!(foo))' جایگزین شود) میشود.
- x##
- (نیازمند فعال بودن گزینهٔ EXTENDED_GLOB است.) با یک یا چند بار تکرار الگوی x مطابقت میکند. این عملگر تقدم بالایی دارد؛ `12##' معادل `1(2##)' است، نه `(12)##'. بیش از دو نویسهٔ `#' فعال نمیتوانند کنار یکدیگر ظاهر شوند. (به تداخل احتمالی با مشخصکنندههای الگو (glob qualifiers) در قالب `1(2##)' توجه داشته باشید که بنابراین باید از آن اجتناب شود.).SS "عملگرهای گلوبینگ شبیه ksh (ksh-like Glob Operators)" اگر گزینهٔ KSH_GLOB تنظیم شده باشد، اثر پرانتزها میتواند با قرار گرفتن یکی از نویسههای `@'، `*'، `+'، `?' یا `!' در پیش از آن تغییر یابد. برای داشتن اثرات ویژه نیازی نیست این نویسه بدون نقلقول باشد، اما `(' باید بدون نقلقول باشد.
- @(...)
- تطابق با الگوی درون پرانتز. (مانند `(...)'.)
- *(...)
- تطابق با هر تعداد تکرار. (مانند `(...)#'، به جز اینکه جستجوی بازگشتی دایرکتوری پشتیبانی نمیشود.)
- +(...)
- تطابق با حداقل یک تکرار. (مانند `(...)##'، به جز اینکه جستجوی بازگشتی دایرکتوری پشتیبانی نمیشود.)
- ?(...)
- تطابق با صفر یا یک تکرار. (مانند `(|...)'.)
- !(...)
- تطابق با هر چیزی بهجز عبارت درون پرانتز. (مانند `(^(...))'.)
اولویت (Precedence)
اولویت عملگرهای ارائهشده در بالا از (بالاترین) `^'، `/'، `~'، `|' (پایینترین) است؛ بقیه عملگرها صرفاً از چپ به راست به عنوان بخشی از یک رشته در نظر گرفته میشوند، و `#' و `##' بر کوتاهترین واحد ممکن پیش از خود (یعنی یک نویسه، `?'، `[...]'، `<...>'، یا یک عبارت درون پرانتز) اعمال میشوند. همانطور که در بالا ذکر شد، یک `/' که به عنوان جداکننده دایرکتوری استفاده میشود نباید درون پرانتز ظاهر شود، در حالی که `|' باید درون آن قرار گیرد؛ در الگوهایی که در زمینههایی غیر از تولید نام فایل استفاده میشوند (برای مثال در دستورهای case و آزمونهای درون `[[...]]')، نویسهٔ `/' خاص نیست؛ و همچنین `/' بعد از یک `~' که بیرون پرانتز در یک الگوی نام فایل ظاهر شود نیز خاص نیست.
پرچمهای گلوبینگ (Globbing Flags)
پرچمهای گوناگونی وجود دارند که بر هر متنی در سمت راست خود تا انتهای گروه دربرگیرنده یا تا انتهای الگو تأثیر میگذارند؛ این پرچمها نیازمند گزینهٔ EXTENDED_GLOB هستند. همه آنها به شکل (#X) هستند که در آن X میتواند یکی از حالتهای زیر را داشته باشد:
- i
- غیرحساس به حروف بزرگ و کوچک: نویسههای بزرگ یا کوچک در الگو با نویسههای بزرگ یا کوچک تطابق مییابند.
- l
- نویسههای کوچک در الگو با نویسههای بزرگ یا کوچک تطابق مییابند؛ نویسههای بزرگ در الگو همچنان تنها با نویسههای بزرگ تطابق پیدا میکنند.
- I
- حساس به حروف بزرگ و کوچک: بهطور محلی اثر i یا l را از آن نقطه به بعد باطل میکند.
- b
- فعالسازی ارجاع به عقب (backreference) برای گروههای پرانتزی در الگو؛ این قابلیت در فرایند تولید نام فایل کار نمیکند. هنگامی که الگویی با مجموعهای از پرانتزهای فعال تطابق یابد، رشتههای تطبیقیافته با گروهها در آرایهٔ $match، اندیسهای آغاز پرانتزهای تطبیقیافته در آرایهٔ $mbegin، و اندیسهای پایان در آرایهٔ $mend ذخیره میشوند، به طوری که نخستین عنصر هر آرایه متناظر با نخستین گروه پرانتزی است، و به همین ترتیب. این آرایهها از جهات دیگر برای شل خاص نیستند. اندیسها از همان قواعد جایگزینی پارامتر استفاده میکنند، بهگونهای که عناصر $mend و $mbegin میتوانند در اندیسها به کار روند؛ گزینهٔ KSH_ARRAYS نیز رعایت میشود. مجموعههای پرچمهای گلوبینگ به عنوان گروههای پرانتزی در نظر گرفته نمیشوند؛ تنها به نه پرانتز فعال نخست میتوان ارجاع داد.
برای مثال،
foo="a_string_with_a_message"
if [[ $foo = (a|an)_(#b)(*) ]]; then
print ${foo[$mbegin[1],$mend[1]]}
fi
عبارت `string_with_a_message' را چاپ میکند. توجه داشته باشید که نخستین مجموعه پرانتز پیش از (#b) قرار دارد و ارجاع به عقب ایجاد نمیکند.
ارجاعهای به عقب با تمامی اشکال تطبیق الگو بهجز تولید نام فایل کار میکنند، اما توجه داشته باشید که هنگام انجام تطبیق بر روی یک آرایه کامل، مانند ${array#pattern}، یا یک جایگزینی سراسری، مانند ${param//pat/repl}، تنها دادههای مربوط به آخرین تطابق در دسترس باقی میمانند. در مورد جایگزینیهای سراسری این رفتار ممکن است همچنان مفید باشد. مثال مربوط به پرچم m در زیر را ببینید.
شمارهگذاری ارجاعهای به عقب دقیقاً از ترتیب پرانتزهای بازشده از چپ به راست در رشتهٔ الگو پیروی میکند، اگرچه مجموعههای پرانتز ممکن است تودرتو باشند. قوانین ویژهای برای پرانتزهایی که به دنبال آنها `#' یا `##' آمده است وجود دارد. تنها آخرین تطابق پرانتز به خاطر سپرده میشود: برای مثال، در `[[ abab = (#b)([ab])# ]]'، تنها `b' نهایی در match[1] ذخیره میشود. بنابراین ممکن است برای تطابق کامل بخش، پرانتزهای اضافی لازم باشد: برای مثال، از `X((ab|cd)#)Y' برای تطابق با کل یک رشته از `ab' یا `cd' بین `X' و `Y' استفاده کنید، و به جای $match[2] از مقدار $match[1] بهره ببرید.
اگر تطابق با شکست مواجه شود هیچیک از پارامترها تغییر نمیکنند، بنابراین در برخی موارد ممکن است نیاز باشد آنها از پیش مقداردهی اولیه شوند. اگر برخی از ارجاعهای به عقب در تطابق شکست بخورند -- که این حالت در صورتی رخ میدهد که آنها در یک شاخهٔ جایگزین ناموفق باشند، یا اگر به دنبال آنها # آمده باشد و صفر بار تطابق یابند -- آنگاه رشتهٔ تطبیقیافته روی رشتهٔ تهی تنظیم میشود، و اندیسهای شروع و پایان روی -1 تنظیم میگردند.
تطبیق الگو با ارجاع به عقب کمی کندتر از حالت بدون آن است.
- B
- غیرفعالسازی ارجاع به عقب، که اثر پرچم b را از آن نقطه به بعد باطل میکند.
- cN,M
- پرچم (#cN,M) در هر جایی که عملگرهای # یا ## قابل استفاده باشند میتواند به کار رود به جز در عبارتهای `(*/)#' و `(*/)##' در تولید نام فایل، جایی که `/' معنای ویژهای دارد؛ این پرچم نمیتواند با دیگر پرچمهای گلوبینگ ترکیب شود و در صورت قرارگیری در جای نادرست خطای الگوی نامعتبر (bad pattern) رخ میدهد. این پرچم معادل شکل {N,M} در عبارتهای منظم است. نویسه یا گروه پیشین باید بین N و M بار، شامل هر دو، تطابق یابد. شکل (#cN) دقیقاً نیازمند N تطابق است؛ (#c,M) معادل تعیین N به صورت 0 است؛ (#cN,) مشخص میکند که هیچ حد بالایی برای تعداد تطابقها وجود ندارد.
- m
- تنظیم ارجاعها به دادههای تطابق برای کل رشتهٔ تطبیقیافته؛ این عمل مشابه ارجاع به عقب است و در فرایند تولید نام فایل کار نمیکند. این پرچم باید در انتهای الگو فعال باشد، یعنی نسبت به یک گروه محلی نباشد. پارامترهای $MATCH، $MBEGIN و $MEND به ترتیب روی رشتهٔ تطبیقیافته و اندیسهای آغاز و پایان رشته تنظیم خواهند شد. این قابلیت بیش از همه در جایگزینی پارامتر کاربرد دارد، زیرا در غیر این صورت رشتهٔ تطبیقیافته از پیش مشخص است.
برای مثال،
arr=(veldt jynx grimps waqf zho buck)
print ${arr//(#m)[aeiou]/${(U)MATCH}}
تمام موارد تطابق (یعنی تمام حروف صدادار) را به حروف بزرگ تبدیل کرده و `vEldt jynx grImps wAqf zhO bUck' را چاپ میکند.
برخلاف ارجاعهای به عقب، هیچ جریمهٔ سرعتی برای استفاده از ارجاعهای تطابق وجود ندارد، مگر جایگزینیهای اضافی لازم برای رشتههای جایگزین در مواردی شبیه مثال ارائهشده.
- M
- غیرفعالسازی پرچم m، بنابراین هیچ ارجاعی به دادههای تطابق ایجاد نخواهد شد.
- anum
- تطبیق تقریبی: تعداد num خطا در رشتهٔ تطبیقیافته توسط الگو مجاز است. قوانین مربوط به این قابلیت در زیربخش بعدی توضیح داده شده است.
- s, e
- برخلاف سایر پرچمها، اینها تنها اثر محلی دارند و هرکدام باید به تنهایی ظاهر شوند: `(#s)' و `(#e)' تنها شکلهای معتبر هستند. پرچم `(#s)' تنها در ابتدای رشتهٔ آزمون موفق میشود، و پرچم `(#e)' تنها در انتهای رشتهٔ آزمون به موفقیت میرسد؛ آنها معادل `^' و `$' در عبارتهای منظم استاندارد هستند. این پرچمها برای تطبیق بخشهای مسیر در الگوهایی غیر از تولید نام فایل مفید هستند (جایی که بخشهای مسیر در هر صورت به صورت جداگانه پردازش میشوند). برای مثال، `*((#s)|/)test((#e)|/)*' با بخش مسیر `test' در هر یک از رشتههای زیر تطابق مییابد: test، test/at/start، at/end/test، in/test/middle. کاربرد دیگر در جایگزینی پارامتر (parameter substitution) است؛ برای نمونه `${array/(#s)A*Z(#e)}' تنها عنصرهایی از یک آرایه را حذف خواهد کرد که با الگوی کامل `A*Z' مطابقت داشته باشند. راههای دیگری نیز برای انجام بسیاری از عملیاتهای اینچنینی وجود دارد، با این حال ترکیب عملیاتهای جایگزینی `/' و `//' با پرچمهای `(#s)' و `(#e)' روشی ساده و بهیادماندنی فراهم میآورد.
توجه
داشته
باشید که
گزارههایی
به شکل `(^(#s))'
نیز کار
میکنند،
یعنی هر
جایی به جز
ابتدای
رشته را
مطابقت
میدهند،
اگرچه این
در واقع به
معنای «هر
چیزی به جز
یک بخش با
طول صفر در
ابتدای
رشته» است؛
برای تطبیق
یک بخش با
طول صفر از
رشته که در
ابتدا
نباشد،
باید از
`(""~(#s))'
استفاده
کنید.
- q
- یک `q' و هر آنچه تا پرانتز بسته پرچمهای globbing بیاید توسط کد تطبیق الگو نادیده گرفته میشود. این قابلیت برای پشتیبانی از استفاده از توصیفگرهای glob در نظر گرفته شده است؛ بخش زیر را ببینید. نتیجه این است که الگوی `(#b)(*).c(#q.)' را میتوان هم برای globbing و هم برای تطبیق با یک رشته به کار برد. در حالت اول، `(#q.)' به عنوان یک توصیفگر glob در نظر گرفته میشود و `(#b)' سودی نخواهد داشت، در حالی که در حالت دوم `(#b)' برای ارجاعهای پسرو (backreferences) مفید است و `(#q.)' نادیده گرفته میشود. توجه داشته باشید که تغییردهندههای دونقطه (colon modifiers) در توصیفگرهای glob نیز در تطبیق الگوی معمولی اعمال نمیشوند.
- u
- با در نظر گرفتن اینکه پوسته با MULTIBYTE_SUPPORT کامپایل شده باشد، locale فعلی در تشخیص وجود نویسههای چندبایتی در الگو رعایت میشود. این پرچم گزینهٔ MULTIBYTE را بازنویسی میکند؛ رفتار پیشفرض از این گزینه گرفته میشود. با U مقایسه کنید. (راهنمای یادآوری: معمولاً نویسههای چندبایتی از Unicode در کدگذاری UTF-8 هستند، اگرچه هر افزونهای از ASCII که توسط کتابخانهٔ سیستم پشتیبانی شود ممکن است مورد استفاده قرار گیرد.)
- U
- همهٔ نویسهها تکبایتی در نظر گرفته میشوند. برعکسِ u است. این پرچم گزینهٔ MULTIBYTE را لغو میکند.
برای نمونه، رشتهٔ آزمایشی fooxx میتواند با الگوی (#i)FOOXX تطبیق یابد، اما با (#l)FOOXX، (#i)FOO(#I)XX یا ((#i)FOOX)X مطابقت ندارد. رشتهٔ (#ia2)readme تطبیق غیرحساس به بزرگی و کوچکی حروف را برای readme با حداکثر دو خطا مشخص میکند.
هنگام استفاده از نحو ksh برای گروهبندی، هر دو گزینهٔ KSH_GLOB و EXTENDED_GLOB باید فعال باشند و پیش از پرانتز باز باید @ قرار گیرد. همچنین دقت کنید که پرچمها روی حروف داخل گروههای [...] تأثیری ندارند، به عبارت دیگر (#i)[a-z] همچنان تنها با حروف کوچک مطابقت مییابد. در نهایت، توجه داشته باشید که هنگام بررسی کل مسیرها بدون حساسیت به حروف بزرگ و کوچک، باید تمام دایرکتوریها برای همهٔ فایلهای منطبق جستجو شوند، به گونهای که الگویی به شکل (#i)/foo/bar/... بالقوه کند خواهد بود.
تطبیق تقریبی (Approximate Matching)
در تطبیق تقریبی، پوسته شمارش خطاهای پیداشده را نگه میدارد که نمیتواند از تعداد مشخصشده در پرچمهای (#anum) فراتر رود. چهار نوع خطا شناسایی میشوند:
- 1.
- نویسههای متفاوت، مانند fooxbar و fooybar.
- 2.
- جابهجایی نویسهها، مانند banana و abnana.
- 3.
- یک نویسهٔ مفقود در رشتهٔ هدف، مانند الگوی road و رشتهٔ هدف rod.
- 4.
- یک نویسهٔ اضافی ظاهر شده در رشتهٔ هدف، مانند stove و strove.
بنابراین، الگوی (#a3)abcd با dcba تطبیق مییابد که خطاهای آن ناشی از دو بار استفاده از قاعدهٔ اول و یک بار از قاعدهٔ دوم با گروهبندی رشته به صورت [d][cb][a] و [a][bc][d] است.
بخشهای غیرلفظی الگو باید به صورت دقیق تطبیق یابند، از جمله نویسهها در محدودههای نویسهای؛ از این رو (#a1)??? با اعمال قاعدهٔ ۴ بر روی یک بخش خالی از الگو، با رشتههایی به طول چهار تطبیق مییابد، اما با رشتههایی به طول دو تطبیق ندارد، زیرا همهٔ ?ها باید مطابقت داشته باشند. سایر نویسههایی که باید دقیقاً تطبیق داده شوند نقطههای ابتدایی نام فایلها (مگر اینکه گزینهٔ GLOB_DOTS تنظیم شده باشد)، و تمام اسلشها در نام فایلها هستند؛ بنابراین a/bc با ab/c دارای دو خطا است (اسلش نمیتواند با نویسهٔ دیگری جابهجا شود). به همین ترتیب، خطاها برای رشتههای غیرمتوالی در الگو به صورت جداگانه شمرده میشوند، به طوری که (ab|cd)ef با aebf دارای دو خطا است.
هنگام استفاده از استثنا به وسیله عملگر ~، تطبیق تقریبی برای بخش مستثنیشده کاملاً به طور جداگانه در نظر گرفته میشود و باید جداگانه فعال گردد. بدین ترتیب، (#a1)README~READ_ME با READ.ME تطبیق مییابد اما با READ_ME خیر، زیرا READ_ME انتهایی بدون تقریب تطبیق داده میشود. با این حال، (#a1)README~(#a1)READ_ME با هیچ الگویی به شکل READ?ME تطبیق نمییابد زیرا اکنون تمام این اَشکال مستثنی شدهاند.
به جز در موارد استثنا، تنها یک شمارش کلی برای خطاها وجود دارد؛ با این حال، حداکثر خطاهای مجاز را میتوان به صورت محلی تغییر داد و این کار با گروهبندی قابل محدودسازی است. برای نمونه، (#a1)cat((#a0)dog)fox در مجموع یک خطا را مجاز میداند که نباید در بخش dog رخ دهد، و الگوی (#a1)cat(#a0)dog(#a1)fox معادل آن است. توجه داشته باشید نقطهای که خطا برای نخستین بار در آن پیدا میشود، نقش حیاتی در تعیین استفاده از تقریب دارد؛ برای نمونه، (#a1)abc(#a0)xyz با abcdxyz مطابقت نخواهد داشت، زیرا خطا در `x' رخ میدهد، جایی که تطبیق تقریبی غیرفعال شده است.
بخشهای کامل مسیر ممکن است به صورت تقریبی تطبیق داده شوند، به طوری که `(#a1)/foo/d/is/available/at/the/bar' یک خطا را در هر بخشی از مسیر مجاز میداند. با این حال این روش بسیار کمبازدهتر از حالت بدون (#a1) است، چرا که هر دایرکتوری در مسیر باید برای تطبیق تقریبی احتمالی پیمایش شود. بهترین کار این است که (#a1) پس از بخشهایی از مسیر که از درستی آنها اطمینان وجود دارد، قرار گیرد. بخشی از مسیر به شکل `(foo/)#' با مسیری شامل صفر یا چند دایرکتوری که با الگوی foo مطابقت دارند، تطبیق مییابد.
به عنوان یک روش کوتاهتر، `**/' معادل با `(*/)#' است؛ توجه داشته باشید که بنابراین، این ساختار با فایلهای موجود در دایرکتوری جاری و همچنین زیردایرکتوریها تطبیق داده میشود. بنابراین:
ls -ld -- (*/)#bar
یا
ls -ld -- **/bar
یک جستجوی بازگشتی دایرکتوری برای فایلهایی به نام `bar' انجام میدهد (که احتمالاً شامل فایل `bar' در دایرکتوری جاری نیز میشود). این ساختار پیوندهای نمادین (symbolic links) را دنبال نمیکند؛ شکل جایگزین `***/' این کار را انجام میدهد، اما در سایر موارد کاملاً مشابه است. هیچیک از این دو را نمیتوان با سایر انواع تطبیق الگو (globbing) در همان بخش مسیر ترکیب کرد؛ در این حالت، عملگرهای `*' به رفتار معمول خود برمیگردند.
در صورتی که گزینهٔ GLOB_STAR_SHORT تنظیم شده باشد، اشکال حتی کوتاهتری نیز در دسترس هستند. در آن حالت، اگر بلافاصله پس از یک ** یا *** نویسهٔ / نیاید، طوری با آنها برخورد میشود که گویی هم یک / و هم یک * دیگر وجود دارند. از این رو:
setopt GLOBSTARSHORT ls -ld -- **.c
معادل است با
ls -ld -- **/*.c
توصیفکنندههای تطبیق الگو (Glob Qualifiers)
الگوهایی که برای تولید نام فایل به کار میروند میتوانند به فهرستی از توصیفکنندهها درون پرانتز ختم شوند. این توصیفکنندهها مشخص میکنند که کدامیک از نامفایلهایی که در غیر این صورت با الگوی دادهشده تطبیق دارند، در فهرست آرگومانها درج خواهند شد.
اگر گزینهٔ BARE_GLOB_QUAL تنظیم شده باشد، یک جفت پرانتز در انتهای الگو که شامل نویسههای `|' یا `(' (یا `~' در صورتی که نویسهٔ ویژه باشد) نباشد، به عنوان مجموعهای از توصیفکنندههای glob در نظر گرفته میشود. یک زیرعبارت glob که در حالت عادی به عنوان توصیفکننده در نظر گرفته میشود، برای نمونه `(^x)'، میتواند با دوبرابر کردن پرانتزها مجبور شود که به عنوان بخشی از الگوی glob در نظر گرفته شود، که در این حالت `((^x))' تولید میشود.
اگر گزینهٔ EXTENDED_GLOB تنظیم شده باشد، نحو دیگری برای توصیفکنندههای glob در دسترس است، یعنی `(#qx)' که در آن x هر یک از همان توصیفکنندههای بهکاررفته در ساختار دیگر است. توصیفکنندهها همچنان باید در انتهای الگو بیایند. با این حال، با این نحو میتوان چندین توصیفکنندهٔ glob را به صورت زنجیرهای به یکدیگر متصل کرد. با آنها مانند یک AND منطقی از مجموعههای جداگانهٔ پرچمها رفتار میشود. همچنین، از آنجا که این نحو بدون ابهام است، تا زمانی که پرانتزهای موجود در آن متوازن باشند، با عبارت به عنوان توصیفکنندههای glob برخورد خواهد شد؛ حضور نویسههای `|' یا `(' یا `~' این رفتار را باطل نمیکند. توجه داشته باشید که توصیفکنندهها به این شکل حتی اگر یک توصیفکنندهٔ سادهٔ glob نیز در انتهای الگو وجود داشته باشد شناسایی میشوند، برای نمونه `*(#q*)(.)' در صورت فعال بودن هر دو گزینه، فایلهای عادی اجرایی را شناسایی خواهد کرد؛ با این حال، احتمالاً برای وضوح بیشتر باید از نحو ترکیبی اجتناب کرد. توجه داشته باشید که در شرطهایی که از ساختار `[[' استفاده میکنند، حضور یک عبارت درون پرانتز به شکل (#q...) در انتهای یک رشته نشان میدهد که باید تطبیق الگو (globbing) انجام شود؛ این عبارت میتواند شامل توصیفکنندههای glob باشد، اما شکل سادهٔ (#q) نیز معتبر است. این مورد در مورد سمت راست عملگرهای تطبیق الگو صدق نمیکند، زیرا این نحو از پیش دارای معنای خاصی است.
یک توصیفکننده میتواند هر یک از موارد زیر باشد:
- /
- دایرکتوریها
- F
- دایرکتوریهای «پر» (یعنی غیرخالی). توجه داشته باشید که مفهوم معکوس (^F) به دایرکتوریهای خالی و همهٔ غیردایرکتوریها بسط مییابد. برای دایرکتوریهای خالی از (/^F) استفاده کنید.
- .
- فایلهای عادی (plain files)
- @
- پیوندهای نمادین (symbolic links)
- =
- سوکتها (sockets)
- p
- لولههای نامگذاریشده (FIFOs)
- *
- فایلهای عادی قابل اجرا (0100 یا 0010 یا 0001)
- %
- فایلهای دستگاه (ویژهٔ نویسهای یا بلوکی)
- %b
- فایلهای ویژهٔ بلوکی (block special files)
- %c
- فایلهای ویژهٔ نویسهای (character special files)
- r
- فایلهای قابل خواندن توسط مالک (0400)
- w
- فایلهای قابل نوشتن توسط مالک (0200)
- x
- فایلهای قابل اجرا توسط مالک (0100)
- A
- فایلهای قابل خواندن توسط گروه (0040)
- I
- فایلهای قابل نوشتن توسط گروه (0020)
- E
- فایلهای قابل اجرا توسط گروه (0010)
- R
- فایلهای قابل خواندن برای همگان (0004)
- W
- فایلهای قابل نوشتن برای همگان (0002)
- X
- فایلهای قابل اجرا برای همگان (0001)
- s
- فایلهای با بیت setuid (04000)
- S
- فایلهای با بیت setgid (02000)
- t
- فایلهای دارای بیت چسبنده یا sticky bit (01000)
- fspec
- فایلهایی با حقوق دسترسی مطابق با spec. این spec میتواند یک عدد اکتال (هشتهشتی) باشد که اختیاری پیش از آن یک `='، یک `+' یا یک `-' قرار میگیرد. اگر هیچیک از این نویسهها داده نشود، رفتار مشابه `=' خواهد بود. عدد اکتال بیتهای حالت مورد انتظار را مشخص میکند؛ اگر با یک `=' ترکیب شود، مقدار دادهشده باید دقیقاً با حالتهای فایل (file-modes) مطابقت داشته باشد؛ با یک `+'، دستکم بیتهای موجود در عدد دادهشده باید در حالتهای فایل تنظیم شده باشند؛ و با یک `-'، بیتهای موجود در آن عدد نباید تنظیم شده باشند. قرار دادن یک `?' به جای یک رقم اکتال در هر کجای عدد تضمین میکند که بیتهای متناظر در حالتهای فایل بررسی نمیشوند؛ این ویژگی تنها در ترکیب با `=' مفید است.
اگر پس از توصیفکنندهٔ `f' هر نویسهٔ دیگری بیاید، هر چیزی تا نویسهٔ منطبق بعدی (`['، `{' و `<' به ترتیب با `]'، `}' و `>' مطابقت دارند، و هر نویسهٔ دیگر با خودش مطابقت دارد) به عنوان فهرستی از sub-specهای جداشده با ویرگول در نظر گرفته میشود. هر sub-spec میتواند یک عدد اکتال مطابق با توضیحات بالا باشد، یا فهرستی از هر یک از نویسههای `u'، `g'، `o' و `a'، به دنبال یک `='، یک `+' یا یک `-'، و پس از آن فهرستی از هر یک از نویسههای `r'، `w'، `x'، `s' و `t' یا یک رقم اکتال باشد. اولین فهرست نویسهها مشخص میکند که کدام حقوق دسترسی باید بررسی شوند. اگر `u' داده شود، دسترسیهای مالک فایل بررسی میشوند؛ اگر `g' داده شود، دسترسیهای گروه بررسی میشوند؛ `o' به معنای آزمودن دسترسیهای سایر کاربران است، و `a' میگوید که هر سه گروه بررسی شوند. نویسههای `='، `+' و `-' مجدداً نحوهٔ بررسی حالتها را مشخص میکنند و همان معنایی را دارند که در اولین شکل بالا شرح داده شد. فهرست دوم نویسهها در نهایت مشخص میکند که کدام حقوق دسترسی مورد انتظار هستند: `r' برای دسترسی خواندن، `w' برای دسترسی نوشتن، `x' برای حق اجرای فایل (یا جستجو در دایرکتوری)، `s' برای بیتهای setuid و setgid، و `t' برای بیت چسبنده (sticky bit)..PP بنابراین، `*(f70?)' فایلهایی را ارائه میدهد که مالک برای آنها مجوزهای خواندن، نوشتن و اجرا دارد، و سایر اعضای گروه هیچ حقی ندارند، صرفنظر از مجوزهای سایر کاربران. الگوی `*(f-100)' همهٔ فایلهایی را برمیگرداند که مالک برای آنها مجوز اجرا ندارد، و `*(f:gu+w,o-rx:)' فایلهایی را ارائه میدهد که مالک و سایر اعضای گروه حداقل مجوز نوشتن را داشته، و سایر کاربران مجوز خواندن یا اجرا ندارند.
- estring
- +cmd
- رشتهٔ string به عنوان کد شل اجرا خواهد شد. نام فایل در فهرست گنجانده خواهد شد اگر و تنها اگر کد یک وضعیت صفر بازگرداند (معمولاً وضعیت خروج آخرین دستور).
در حالت نخست، اولین نویسه پس از `e' به عنوان جداکننده استفاده خواهد شد و هر چیزی تا جداکنندهٔ منطبق بعدی به عنوان string در نظر گرفته میشود؛ `['، `{' و `<' به ترتیب با `]'، `}' و `>' تطبیق مییابند، در حالی که هر نویسهٔ دیگر با خودش مطابقت دارد. توجه داشته باشید که بسطها باید در string در نقلقول قرار گیرند تا از بسط یافتن آنها پیش از انجام globbing جلوگیری شود. سپس string به عنوان کد شل اجرا میشود. رشتهٔ globqual در طول مدت اجرا به آرایهٔ zsh_eval_context اضافه میشود.
در طول اجرای string، نام فایلی که در حال حاضر بررسی میشود در پارامتر REPLY در دسترس است؛ این پارامتر ممکن است به رشتهای تغییر داده شود تا به جای نام فایل اصلی در فهرست درج گردد. علاوه بر این، پارامتر reply میتواند به یک آرایه یا یک رشته تنظیم شود که مقدار REPLY را لغو (override) میکند. در صورت تنظیم به یک آرایه، آرایه کلمه به کلمه در خط فرمان درج میشود.
برای مثال، فرض کنید یک دایرکتوری تنها شامل یک فایل `lonely' باشد. در این صورت عبارت `*(e:'reply=(${REPLY}{1,2})':)' باعث خواهد شد کلمات `lonely1' و `lonely2' در خط فرمان درج شوند. به نقلقولگذاری string توجه کنید.
شکل +cmd همان اثر را دارد، اما هیچ جداکنندهای در اطراف cmd قرار نمیگیرد. در عوض، cmd طولانیترین دنباله از نویسههای پس از + در نظر گرفته میشود که حروفی-عددی یا زیرخط (underscore) هستند. معمولاً cmd نام یک تابع شل خواهد بود که آزمون مناسب را دربردارد. برای مثال،
nt() { [[ $REPLY -nt $NTREF ]] }
NTREF=reffile
ls -ld -- *(+nt)
تمام فایلهای موجود در دایرکتوری را که اخیراً نسبت به reffile تغییر یافتهاند (جدیدتر هستند)، فهرست میکند.
- ddev
- فایلهای روی دستگاه dev
- l[-|+]ct
- فایلهایی با تعداد پیوند کمتر از ct (-)، بیشتر از ct (+)، یا برابر با ct
- U
- فایلهایی که مالک آنها شناسه کاربری مؤثر (effective user ID) است
- G
- فایلهایی که مالک آنها شناسه گروه مؤثر (effective group ID) است
- uid
- فایلهایی که مالک آنها شناسه کاربری id است در صورتی که یک عدد باشد. در غیر این صورت، id یک نام کاربری را مشخص میکند: نویسهٔ بعد از `u' به عنوان یک جداکننده در نظر گرفته میشود و رشتهٔ میان آن و جداکننده منطبق بعدی به عنوان نام کاربری تلقی خواهد شد. جداکنندههای آغازین `['، `{' و `<' به ترتیب با جداکنندههای پایانی `]'، `}' و `>' تطبیق مییابند؛ هر نویسهٔ دیگر با خودش مطابقت دارد. فایلهای انتخابشده آنهایی هستند که در مالکیت این کاربر باشند. برای نمونه، `u:foo:' یا `u[foo]' فایلهای متعلق به کاربر `foo' را انتخاب میکند.
- gid
- مشابه uid اما با شناسهها یا نامهای گروه
- a[Mwhms][-|+]n
- فایلهایی که دقیقاً n روز پیش مورد دسترسی قرار گرفتهاند. فایلهای مورد دسترسی در طول n روز گذشته با استفاده از یک مقدار منفی برای n (-n) انتخاب میشوند. فایلهایی که بیش از n روز پیش مورد دسترسی قرار گرفتهاند با یک مقدار مثبت n (+n) انتخاب میشوند. مشخصکنندههای اختیاری یکا شامل `M'، `w'، `h'، `m' یا `s' (مانند `ah5') باعث میشوند بررسی به ترتیب بر حسب ماه (۳۰ روزه)، هفته، ساعت، دقیقه یا ثانیه به جای روز انجام شود. استفادهٔ صریح از `d' برای روز نیز مجاز است.
هر بخش اعشاری از اختلاف بین زمان دسترسی و زمان فعلی در یکای مربوطه، در مقایسه نادیده گرفته میشود. برای نمونه، `echo *(ah-5)' فایلهایی را چاپ میکند که در طول پنج ساعت گذشته مورد دسترسی قرار گرفتهاند، در حالی که `echo *(ah+5)' فایلهایی را چاپ میکند که حداقل شش ساعت پیش مورد دسترسی بودهاند، زیرا زمانهای اکیداً بین پنج و شش ساعت به عنوان پنج ساعت در نظر گرفته میشوند.
- m[Mwhms][-|+]n
- مشابه توصیفکنندهٔ دسترسی فایل، به جز اینکه از زمان تغییر محتوای فایل (modification time) استفاده میکند.
- c[Mwhms][-|+]n
- مشابه توصیفکنندهٔ دسترسی فایل، به جز اینکه از زمان تغییر وضعیت اینود فایل (inode change time) استفاده میکند.
- L[+|-]n
- فایلهایی با طول کمتر از n بایت (-)، بیشتر از n بایت (+)، یا دقیقاً برابر با n بایت.
اگر این پرچم بلافاصله با یک مشخصکننده اندازه شامل `k' (`K')، `m' (`M') یا `p' (`P') (مانند `Lk-50') همراه شود، بررسی به جای آن بر حسب کیلوبایت، مگابایت، یا بلوک (۵۱۲ بایتی) انجام میگیرد. (در برخی سیستمها مشخصکنندههای اضافی برای گیگابایت، `g' یا `G'، و ترابایت، `t' یا `T' در دسترس است.) اگر یک مشخصکننده اندازه استفاده شود، یک فایل زمانی «دقیقاً» هماندازه تلقی میشود که اندازه فایل گرد شده به سمت بالا به یکای بعدی، با اندازه مورد آزمون برابر باشد. بنابراین `*(Lm1)' با فایلهای از ۱ بایت تا ۱ مگابایت (شامل هر دو) مطابقت دارد. همچنین دقت کنید که مجموعه فایلهای «کمتر از» اندازه مورد آزمون فقط شامل فایلهایی است که با آزمون برابری مطابقت ندارند؛ بنابراین `*(Lm-1)' تنها با فایلهای با اندازهٔ صفر مطابقت دارد.
- ^
- تمام توصیفکنندههای پس از خود را نفی (معکوس) میکند
- -
- بین اعمال توصیفکنندهها بر روی پیوندهای نمادین (حالت پیشفرض) و فایلهایی که به آنها اشاره میکنند (در صورت وجود)، وضعیت را تغییر میدهد؛ هر پیوند نمادینی که فراخوانی سیستمی `stat' برای هدف آن با شکست مواجه شود (علت شکست هرچه که باشد) به عنوان یک فایل مستقل در نظر گرفته میشود
- M
- گزینهٔ MARK_DIRS را برای الگوی فعلی تنظیم میکند
- T
- همانند گزینهٔ LIST_TYPES، یک علامت توصیفکننده در انتهای نام فایلها برای الگوی فعلی میافزاید (بر M اولویت دارد)
- N
- گزینهٔ NULL_GLOB را برای الگوی فعلی تنظیم میکند
- D
- گزینهٔ GLOB_DOTS را برای الگوی فعلی تنظیم میکند
- n
- گزینهٔ NUMERIC_GLOB_SORT را برای الگوی فعلی تنظیم میکند
- Yn
- حالت مدار-کوتاه (short-circuit) را فعال میکند: الگو حداکثر به n نام فایل بسط مییابد. اگر بیش از n تطابق وجود داشته باشد، فقط نخستین n تطابق به ترتیب پیمایش دایرکتوری در نظر گرفته خواهند شد.
اگر هیچ توصیفکنندهٔ oc استفاده نشده باشد، متضمن oN است.
- oc
- مشخص میکند که نام فایلها چگونه باید مرتب شوند. مقادیر زیر برای c به روشهای زیر مرتبسازی را انجام میدهند:
- n
- بر اساس نام.
- L
- بر اساس اندازه (طول) فایلها.
- l
- بر اساس تعداد پیوندها..TP a بر اساس زمان آخرین دسترسی، جدیدترینها در ابتدا.
- m
- بر اساس زمان آخرین تغییر، جدیدترینها در ابتدا.
- c
- بر اساس زمان آخرین تغییر inode، جدیدترینها در ابتدا.
- d
- بر اساس دایرکتوریها: در هر سطح از جستوجو، فایلهای موجود در زیردایرکتوریها پیش از فایلهای دایرکتوری جاری ظاهر میشوند -- بهتر است این مورد با سایر معیارها ترکیب شود، برای نمونه «odon» برای مرتبسازی نام فایلها در همان دایرکتوری.
- N
- هیچ مرتبسازیای انجام نمیشود.
- estring
- +cmd
- مرتبسازی بر اساس کد پوسته (پایینتر را ببینید).
توجه داشته باشید که تغییردهندههای ^ و - استفاده میشوند، بنابراین «*(^-oL)» فهرستی از تمامی فایلها را با دنبال کردن هرگونه پیوند نمادین، بهترتیب نزولی اندازهٔ فایل مرتب میکند. مگر اینکه از oN استفاده شود، میتوان از چندین مشخصکنندهٔ ترتیب برای رفع موارد تساوی استفاده کرد.
مرتبسازی پیشفرض n (بر اساس نام) است مگر اینکه از توصیفکنندهٔ glob Y استفاده شود، که در این صورت N (مرتبنشده) خواهد بود.
عبارات oe و o+ حالتهای ویژهای هستند؛ به دنبال هر یک از آنها کد پوسته میآید، که بهترتیب همانند توصیفکنندهٔ glob e و توصیفکنندهٔ glob + تحدید حدود میشوند (بالا را ببینید). کد برای هر فایل منطبق اجرا میشود در حالی که مقدار پارامتر REPLY در بدو ورود برابر با نام فایل قرار داده شده و globsort به zsh_eval_context ضمیمه شده است. کد باید پارامتر REPLY را به نحوی تغییر دهد. در هنگام بازگشت، مقدار این پارامتر بهجای نام فایل بهعنوان رشتهای که مرتبسازی باید بر اساس آن انجام شود استفاده میگردد. برخلاف دیگر عملگرهای مرتبسازی، oe و o+ ممکن است تکرار شوند، اما توجه داشته باشید که بیشینهٔ تعداد عملگرهای مرتبسازی از هر نوع که میتوانند در هر عبارت glob بیایند ۱۲ است.
- Oc
- مانند «o»، اما بهصورت نزولی مرتب میکند؛ یعنی «*(^oc)» همانند «*(Oc)» است و «*(^Oc)» همانند «*(oc)»؛ «Od» در هر سطح از جستوجو، فایلهای موجود در دایرکتوری جاری را پیش از فایلهای موجود در زیردایرکتوریها قرار میدهد.
- [beg[,end]]
- مشخص میکند که کدام یک از نامهای فایل منطبقشده باید در فهرست بازگرداندهشده گنجانده شوند. نحو نگارش آن مشابه با اندیسهای آرایه است. beg و end اختیاری میتوانند عبارتهای ریاضی باشند. مانند اندیسگذاری پارامترها، آنها میتوانند منفی باشند تا شمارش از آخرین تطابق به سمت عقب انجام گیرد. برای نمونه: «*(-OL[1,3])» فهرستی از نامهای سه فایل بزرگتر را برمیگرداند.
- Pstring
- عبارت string به عنوان یک کلمهٔ جداگانه به ابتدای هر تطابق glob اضافه خواهد شد. تحدید string به همان شیوهای است که برای آرگومانهای توصیفکنندهٔ glob e که در بالا شرح داده شد انجام میشود. این توصیفکننده میتواند تکرار شود؛ کلمات بهطور جداگانه به ابتدا اضافه میشوند تا خط فرمان نهایی شامل کلمات به همان ترتیبی باشد که در فهرست توصیفکنندههای glob داده شده بودند.
یک کاربرد معمول برای این مورد، افزودن یک گزینه پیش از تمامی موارد وقوع نام فایل است؛ برای مثال، الگوی «*(P:-f:)» آرگومانهای خط فرمان «-f file1 -f file2 ...» را تولید میکند.
اگر تغییردهندهٔ ^ فعال باشد، آنگاه string بهجای اضافه شدن به ابتدا، به انتها اضافه (پسوند) خواهد شد. اضافه کردن به ابتدا و انتها بهطور مستقل انجام میشود، بنابراین هر دو میتوانند روی یک عبارت glob یکسان به کار روند؛ برای نمونه با نوشتن «*(P:foo:^P:bar:^P:baz:)» که آرگومانهای خط فرمان «foo baz file1 bar ...» را تولید میکند.
بیش از یکی از این فهرستها میتوانند با جدا شدن توسط ویرگول با یکدیگر ترکیب شوند. کل فهرست زمانی منطبق میشود که دستکم یکی از زیرفهرستها تطابق داشته باشد (آنها با هم «یا» میشوند و توصیفکنندهها در زیرفهرستها با هم «و» میشوند). با این حال، برخی از توصیفکنندهها مستقل از زیرفهرستی که در آن داده شدهاند، بر تمامی تطابقهای تولیدشده اثر میگذارند. اینها توصیفکنندههای «M»، «T»، «N»، «D»، «n»، «o»، «O» و اندیسهای ارائهشده در براکتها («[...]») هستند.
اگر یک «:» در فهرست توصیفکنندهها ظاهر شود، باقیماندهٔ عبارت درون پرانتز به عنوان یک تغییردهنده تفسیر میشود (بخش «Modifiers» در بخش «History Expansion» را ببینید). هر تغییردهنده باید توسط یک «:» جداگانه معرفی شود. همچنین توجه داشته باشید که نتیجه پس از اعمال تغییر نیازی نیست که حتماً یک فایل موجود باشد. نام هر فایل موجودی میتواند با یک تغییردهنده به شکل «(:...)» دنبال شود حتی اگر هیچ تولید نام فایل واقعی انجام نگیرد، اگرچه توجه داشته باشید که وجود پرانتزها باعث میشود که کل عبارت مشمول هرگونه گزینههای تطبیق الگوی سراسری مانند NULL_GLOB شود. بنابراین:
ls -ld -- *(-/)
تمامی دایرکتوریها و پیوندهای نمادینی که به دایرکتوریها اشاره دارند را فهرست میکند، و
ls -ld -- *(-@)
تمامی پیوندهای نمادین شکسته را فهرست میکند، و
ls -ld -- *(%W)
تمامی فایلهای دستگاه در دایرکتوری جاری که همگان اجازهٔ نوشتن در آنها را دارند فهرست میکند، و
ls -ld -- *(W,X)
تمامی فایلهای موجود در دایرکتوری جاری که قابل نوشتن برای همگان یا قابل اجرا برای همگان هستند را فهرست میکند، و
print -rC1 /tmp/foo*(u0^@:t)
نام پایهٔ (basename) تمامی فایلهای متعلق به root که با رشتهٔ «foo» در /tmp آغاز میشوند را با نادیده گرفتن پیوندهای نمادین خروجی میدهد، و
ls -ld -- *.*~(lex|parse).[ch](^D^l1)
تمامی فایلهایی که تعداد پیوند آنها ۱ است و نامشان شامل یک نقطه است (اما نه آنهایی که با یک نقطه آغاز میشوند، چرا که GLOB_DOTS بهطور صریح خاموش است) را بهجز lex.c، lex.h، parse.c و parse.h فهرست میکند.
print -rC1 b*.pro(#q:s/pro/shmo/)(#q.:s/builtin/shmiltin/)
نشان میدهد که چگونه تغییردهندههای دونقطه و سایر توصیفکنندهها میتوانند به یکدیگر زنجیر شوند. توصیفکنندهٔ معمولی «.» ابتدا اعمال میشود، سپس تغییردهندههای دونقطه به ترتیب از چپ به راست اعمال میگردند. بنابراین اگر EXTENDED_GLOB تنظیم شده باشد و الگوی پایه با فایل عادی builtin.pro منطبق شود، پوسته «shmiltin.shmo» را چاپ خواهد کرد.
| July 12, 2026 | zsh 5.9.2 |