به یاد بیاورید که یک برنامهی jq یک خط لولهی عبارتها است.
تخصیص متغیر از این قاعده پیروی میکند: یک تخصیص متغیر عبارتی است که به این شکل است:
... | expr as $varname | ...
مانند عبارت همانی .، خروجی تخصیص متغیر هم همان ورودی آن است.
تنظیم مقدار متغیر یک «عارضهی جانبی» است.
مثال، که نشان میدهد . بعد از تخصیص همان ورودی اولیه است:
$ jq -c -n '42 | (. * 2) as $double | [., $double]'
[42,84]
دامنهی متغیر «واژگانی» است؛ یعنی متغیر تا پایان خط لوله در دامنه میماند. متغیرهایی که در توابع تعریف میشوند (بعداً به توابع میرسیم) نسبت به آن تابع «محلی» هستند.
اسم متغیر باید با $ شروع شود.
بقیهی اسم متغیر یک شناسه است: با یک حرف یا زیرخط شروع میشود و پس از آن حرف، عدد یا زیرخط میآید.
از کتاب راهنما:
چندین متغیر را میتوان با یک عبارت
asواحد اعلام کرد، به شرط آنکه الگویی بدهید که با ساختار ورودی مطابقت داشته باشد (به این کار «ساختارشکنی» میگویند).
مثالها:
[1, 2, 3] as [$a, $b, $c]
| [$a, $b, $c] # => [1, 2, 3]
{"foo": "bar", "len": [10, 20]} as {foo: $f, len: [$h, $w]}
| [$f, $h, $w] # => ["bar", 10, 20]
تطبیق دادن اسم متغیر با کلید شیء یک میانبر به دست میدهد:
{"x": 4, "y": 7} as {$x, $y}
| [$x, $y] # => [4, 7]
{"foo": "bar", "len": [10, 20]} as {$foo, $len}
| [$foo, $len] # => ["bar", [10, 20]]
همین میانبر در جهت معکوس برای ساخت شیء هم کار میکند
4 as $x | 7 as $y | {$x, $y} # => {"x":4, "y": 7}
همانطور که در مثال بالا دیدید، متغیرها برای نگه داشتن ثابتها به کار میآیند. بهتر است برای ثابتها یک اسم بگذارید تا اینکه «اعداد جادویی» در کد ظاهر شوند.
اغلب خواناتر است که متغیرها را حذف کنید.
محاسبهی میانگین یک فهرست از اعداد را در نظر بگیرید
[2, 4, 8, 7]
| add as $sum
| length as $len
| $sum / $len
در مقایسه با
[2, 4, 8, 7] | add / length
این یکی از قدرتمندترین ویژگیهای jq را نشان میدهد: ورودی یک فیلتر در اختیار هر زیرعبارت قرار میگیرد:
[2,4,8,7] به add داده میشود (که با اعمال عملگر + روی همهی عناصر، اعداد را جمع میکند)[2,4,8,7] به length هم داده میشودjq که در تمرین یادگیری به آنها نیاز دارید//
عبارت a // b اگر a «غلط» یا null باشد، b را خروجی میدهد؛ در غیر این صورت a را خروجی میدهد.
در بافت تنظیم یک متغیر، این برای فراهم کردن یک مقدار پیشفرض خیلی به کار میآید:
(.input.theAnswer // 42) as $answer | ...
+، - و * عملگرهای معمول جمع، تفریق و ضرب عددی هستند.در این تمرین قرار است کدی بنویسید که کمکتان کند از کتاب آشپزی محبوبتان یک لازانیای عالی درست کنید.
چهار کار دارید که همه به زمان صرفشده برای پخت لازانیا مربوط میشوند.
یک ثابت به اسم $expected_minutes_in_oven تعریف کنید.
طبق کتاب آشپزی، زمان مورد انتظار پخت در فر ۴۰ دقیقه است:
$ jq -n -f lasagna.jq
{
"expected_minutes_in_oven": 40,
...
این مقدار، دقیقههای واقعیای را که لازانیا در فر بوده است به عنوان ورودی میگیرد و بر اساس زمان مورد انتظار پخت در فر که در کار قبلی تعریف شد، برمیگرداند که لازانیا باید چند دقیقهی دیگر در فر بماند.
$ echo '{"actual_minutes_in_oven": 18}' | jq -f lasagna.jq
{
"expected_minutes_in_oven": 40,
"remaining_minutes_in_oven": 22,
...
زمان آمادهسازی، مدت زمانی است که طول میکشد تا لازانیا پیش از گذاشتهشدن در فر آماده شود. آماده کردن هر لایه ۲ دقیقه طول میکشد.
$ echo '{"number_of_layers": 3}' | jq -f lasagna.jq
{
...
"preparation_time": 6,
...
محاسبه کنید که در کل چند دقیقه برای پخت لازانیا کار کردهاید. این مقدار، مجموع زمان آمادهسازی و زمانی است که لازانیا تا این لحظه در فر گذرانده است.
$ echo '{"actual_minutes_in_oven": 10, "number_of_layers": 2}' | jq -f lasagna.jq
{
...
"total_time": 14,
...