'\" t .\" Automatically generated by Pandoc 2.12 .\" .TH "JO" "1" "" "User Manuals" "" .hy .SH "نام (NAME)" .PP jo \- تولید خروجی JSON از پوسته .SH "خلاصه دستور (SYNOPSIS)" .PP jo [-p] [-a] [-B] [-D] [-e] [-n] [-v] [-V] [-d keydelim] [-f file] [\[en]] [ [-s|-n|-b] word \&...] .SH "توضیحات (DESCRIPTION)" .PP دستور \f[I]jo\f[R] بر اساس \f[I]word\f[R]هایی که به عنوان آرگومان دریافت می‌کند یا از \f[I]stdin\f[R] می‌خواند، یک رشته JSON در \f[I]stdout\f[R] ایجاد می‌کند. اگر \f[C]-f\f[R] مشخص شده باشد، \f[I]jo\f[R] ابتدا محتویات \f[I]file\f[R] را به عنوان یک شیء یا آرایه JSON بارگذاری کرده، سپس آن را با \f[I]word\f[R]های بعدی پیش از چاپ رشته نهایی JSON در \f[I]stdout\f[R] اصلاح می‌کند. می‌توان \f[I]file\f[R] را به صورت \f[C]-\f[R] مشخص کرد تا از ورودی استاندارد \f[I]jo\f[R] خوانده شود؛ این حالت بر خواندن \f[I]word\f[R]ها از \f[I]stdin\f[R] اولویت دارد. .PP بدون گزینهٔ \f[C]-a\f[R]، این دستور یک شیء تولید می‌کند که در آن هر \f[I]word\f[R] یک جفت \f[C]key=value\f[R] (یا \f[C]key\[at]value\f[R]) است، به‌طوری که \f[I]key\f[R] عنصر شیء JSON و \f[I]value\f[R] مقدار آن خواهد بود. دستور \f[I]jo\f[R] تلاش می‌کند تا نوع \f[I]value\f[R] را حدس بزند تا مقادیر عددی (با استفاده از \f[I]strtod(3)\f[R])، رشته‌ای یا null را در JSON بسازد. .PP یک \f[I]value\f[R] خالی یا ناموجود معمولاً به عنصری با مقدار \f[C]null\f[R] منجر می‌شود. اگر گزینهٔ \f[C]-n\f[R] مشخص شود، این عنصر ایجاد نخواهد شد. .PP دستور \f[I]jo\f[R] معمولاً با \f[I]key\f[R] به عنوان یک مقدار رشته‌ای لفظی (literal) رفتار می‌کند. اگر گزینهٔ \f[C]-d\f[R] مشخص شده باشد، \f[I]key\f[R] به عنوان یک \f[I]مسیر شیء (object path)\f[R] تفسیر خواهد شد، که مؤلفه‌های مجزای آن با اولین نویسهٔ \f[I]keydelim\f[R] از یکدیگر جدا می‌شوند. .PP دستور \f[I]jo\f[R] معمولاً با \f[I]value\f[R] به عنوان یک مقدار رشته‌ای لفظی رفتار می‌کند، مگر اینکه با یکی از نویسه‌های زیر آغاز شود: .PP .TS tab(@); l l. T{ مقدار (value) T}@T{ عملکرد (action) T} _ T{ \[at]file T}@T{ محتوای \f[I]file\f[R] را عیناً جایگزین می‌کند T} T{ %file T}@T{ محتوای \f[I]file\f[R] را به شکل کدگذاری‌شده با base64 جایگزین می‌کند T} T{ :file T}@T{ محتوای \f[I]file\f[R] را به عنوان JSON تفسیر کرده و نتیجه را جایگزین می‌کند T} .TE .PP برای جلوگیری از این تفسیر، نویسهٔ ویژه را با یک بک‌اسلش نادیده‌سازی (escape) کنید. .PP دستور \f[I]jo\f[R] با عبارت \f[C]key\[at]value\f[R] به‌طور ویژه به عنوان عناصر بولی (boolean) در JSON رفتار می‌کند: اگر مقدار با \f[C]T\f[R]، \f[C]t\f[R] آغاز شود، یا مقدار عددی آن بزرگ‌تر از صفر باشد، خروجی \f[C]true\f[R] است، وگرنه \f[C]false\f[R] خواهد بود. .PP هنگامی که گزینهٔ \f[C]-a\f[R] مشخص شود، \f[I]jo\f[R] به جای شیء، یک آرایه ایجاد می‌کند. .PP هنگامی که از عملگر \f[C]:=\f[R] در یک \f[I]word\f[R] استفاده می‌شود، نامِ سمت راستِ \f[C]:=\f[R] فایلی حاوی JSON است که تجزیه شده و به کلید سمت چپ عملگر تخصیص داده می‌شود. فایل می‌تواند به صورت \f[C]-\f[R] تعیین شود تا از ورودی استاندارد \f[I]jo\f[R] خوانده شود..SH "تبدیل نوع (TYPE COERCION)" .PP حدس‌های نوعِ \f[I]jo\f[R] را می‌توان به ازای هر \f[I]word\f[R] با پیشوند کردن \f[C]-s\f[R] برای \f[I]string\f[R] (رشته)، \f[C]-n\f[R] برای \f[I]number\f[R] (عدد)، یا \f[C]-b\f[R] برای \f[I]boolean\f[R] (بولی) بازنویسی کرد. پیش از فهرست \f[I]word\f[R]ها \f[I]باید\f[R] پیشوند \f[C]--\f[R] قرار گیرد تا به \f[I]jo\f[R] نشان داده شود که گزینهٔ سراسری دیگری وجود ندارد. .PP تبدیل نوع به صورت زیر عمل می‌کند: .PP .TS tab(@); l l l l l. T{ word T}@T{ -s T}@T{ -n T}@T{ -b T}@T{ پیش‌فرض T} _ T{ a= T}@T{ \[lq]a\[rq]:\[dq]\[dq] T}@T{ \[lq]a\[rq]:0 T}@T{ \[lq]a\[rq]:false T}@T{ \[lq]a\[rq]:null T} T{ a=string T}@T{ \[lq]a\[rq]:\[lq]string\[rq] T}@T{ \[lq]a\[rq]:6 T}@T{ \[lq]a\[rq]:true T}@T{ \[lq]a\[rq]:\[lq]string\[rq] T} T{ a=\[dq]quoted\[dq] T}@T{ \[lq]a\[rq]:\[lq]\[dq]quoted\[dq]\[rq] T}@T{ \[lq]a\[rq]:8 T}@T{ \[lq]a\[rq]:true T}@T{ \[lq]a\[rq]:\[lq]\[dq]quoted\[dq]\[rq] T} T{ a=12345 T}@T{ \[lq]a\[rq]:\[lq]12345\[rq] T}@T{ \[lq]a\[rq]:12345 T}@T{ \[lq]a\[rq]:true T}@T{ \[lq]a\[rq]:12345 T} T{ a=true T}@T{ \[lq]a\[rq]:\[lq]true\[rq] T}@T{ \[lq]a\[rq]:1 T}@T{ \[lq]a\[rq]:true T}@T{ \[lq]a\[rq]:true T} T{ a=false T}@T{ \[lq]a\[rq]:\[lq]false\[rq] T}@T{ \[lq]a\[rq]:0 T}@T{ \[lq]a\[rq]:false T}@T{ \[lq]a\[rq]:false T} T{ a=null T}@T{ \[lq]a\[rq]:\[dq]\[dq] T}@T{ \[lq]a\[rq]:0 T}@T{ \[lq]a\[rq]:false T}@T{ \[lq]a\[rq]:null T} .TE .PP تبدیل یک رشتهٔ غیرعددی به عدد، \f[I]طول\f[R] رشته را در خروجی تولید می‌کند. .PP تبدیل یک رشتهٔ غیربولی به بولی، در صورت خالی بودن رشته مقدار \f[C]false\f[R] و در غیر این صورت \f[C]true\f[R] را در خروجی تولید می‌کند. .PP تبدیل نوع فقط برای \f[I]word\f[R]های \f[C]key=value\f[R] و \f[I]word\f[R]های مجزا در یک آرایهٔ \f[C]-a\f[R] اعمال می‌شود. تبدیل نوع سایر \f[I]word\f[R]ها هیچ اثری ندارد..SH "مثال‌ها (EXAMPLES)" .PP ایجاد یک شیء. توجه کنید که چگونه مقدار ممیز شناور با قالب‌بندی نادرست به یک رشته تبدیل می‌شود: .IP .nf \f[C] $ jo tst=1457081292 lat=12.3456 cc=FR badfloat=3.14159.26 name=\[dq]JP Mens\[dq] nada= coffee\[at]T {\[dq]tst\[dq]:1457081292,\[dq]lat\[dq]:12.3456,\[dq]cc\[dq]:\[dq]FR\[dq],\[dq]badfloat\[dq]:\[dq]3.14159.26\[dq],\[dq]name\[dq]:\[dq]JP Mens\[dq],\[dq]nada\[dq]:null,\[dq]coffee\[dq]:true} \f[R] .fi .PP چاپ مرتب و خوانا (pretty-print) یک آرایه با فهرستی از فایل‌های دایرکتوری جاری: .IP .nf \f[C] $ jo -p -a * [ \[dq]Makefile\[dq], \[dq]README.md\[dq], \[dq]jo.1\[dq], \[dq]jo.c\[dq], \[dq]jo.pandoc\[dq], \[dq]json.c\[dq], \[dq]json.h\[dq] ] \f[R] .fi .PP ایجاد اشیاء درون اشیاء؛ این قابلیت به این دلیل کار می‌کند که اگر نویسه اول مقدار یک آکولاد باز یا یک براکت باشد، تلاش می‌شود باقی‌مانده آن به عنوان JSON تفسیر و رمزگشایی شود. مراقب فاصله‌ها در رشته‌ها باشید \&... .IP .nf \f[C] $ jo -p name=JP object=$(jo fruit=Orange hungry\[at]0 point=$(jo x=10 y=20 list=$(jo -a 1 2 3 4 5)) number=17) sunday\[at]0 { \[dq]name\[dq]: \[dq]JP\[dq], \[dq]object\[dq]: { \[dq]fruit\[dq]: \[dq]Orange\[dq], \[dq]hungry\[dq]: false, \[dq]point\[dq]: { \[dq]x\[dq]: 10, \[dq]y\[dq]: 20, \[dq]list\[dq]: [ 1, 2, 3, 4, 5 ] }, \[dq]number\[dq]: 17 }, \[dq]sunday\[dq]: false } \f[R] .fi .PP مقادیر بولی به عنوان رشته یا به صورت بولی (به \f[I]switch\f[R] توجه ویژه داشته باشید؛ گزینه \f[C]-B\f[R] تشخیص پیش‌فرض رشته‌های \[lq]\f[C]true\f[R]\[rq]، \[lq]\f[C]false\f[R]\[rq] و \[lq]\f[C]null\f[R]\[rq] را غیرفعال می‌کند): .IP .nf \f[C] $ jo switch=true morning\[at]0 {\[dq]switch\[dq]:true,\[dq]morning\[dq]:false} $ jo -B switch=true morning\[at]0 {\[dq]switch\[dq]:\[dq]true\[dq],\[dq]morning\[dq]:false} \f[R] .fi .PP عناصر (اشیاء و آرایه‌ها) می‌توانند به صورت تو در تو قرار گیرند. مثال زیر یک آرایه با نام \f[I]point\f[R] و یک شیء با نام \f[I]geo\f[R] را تو در تو قرار می‌دهد: .IP .nf \f[C] $ jo -p name=Jane point[]=1 point[]=2 geo[lat]=10 geo[lon]=20 { \[dq]name\[dq]: \[dq]Jane\[dq], \[dq]point\[dq]: [ 1, 2 ], \[dq]geo\[dq]: { \[dq]lat\[dq]: 10, \[dq]lon\[dq]: 20 } } \f[R] .fi .PP همان مثال، با استفاده از مسیرهای شیء (object paths): .IP .nf \f[C] $ jo -p -d. name=Jane point[]=1 point[]=2 geo.lat=10 geo.lon=20 { \[dq]name\[dq]: \[dq]Jane\[dq], \[dq]point\[dq]: [ 1, 2 ], \[dq]geo\[dq]: { \[dq]lat\[dq]: 10, \[dq]lon\[dq]: 20 } } \f[R] .fi .PP بدون \f[C]-d\f[R]، شیء متفاوتی تولید می‌شود: .IP .nf \f[C] $ jo -p name=Jane point[]=1 point[]=2 geo.lat=10 geo.lon=20 { \[dq]name\[dq]: \[dq]Jane\[dq], \[dq]point\[dq]: [ 1, 2 ], \[dq]geo.lat\[dq]: 10, \[dq]geo.lon\[dq]: 20 } \f[R] .fi .PP ایجاد اشیاء یا آرایه‌های خالی، به صورت عمدی یا احتمالی: .IP .nf \f[C] $ jo < /dev/null {} $ MY_ARRAY=(a=1 b=2) $ jo -a \[dq]${MY_ARRAY[\[at]]}\[dq] < /dev/null [\[dq]a=1\[dq],\[dq]b=2\[dq]] \f[R] .fi .PP تبدیل اجباری نوع (Type coercion): .IP .nf \f[C] $ jo -p -- -s a=true b=true -s c=123 d=123 -b e=\[dq]1\[dq] -b f=\[dq]true\[dq] -n g=\[dq]This is a test\[dq] -b h=\[dq]This is a test\[dq] { \[dq]a\[dq]: \[dq]true\[dq], \[dq]b\[dq]: true, \[dq]c\[dq]: \[dq]123\[dq], \[dq]d\[dq]: 123, \[dq]e\[dq]: true, \[dq]f\[dq]: true, \[dq]g\[dq]: 14, \[dq]h\[dq]: true } $ jo -a -- -s 123 -n \[dq]This is a test\[dq] -b C_Rocks 456 [\[dq]123\[dq],14,true,456] \f[R] .fi .PP خواندن مقادیر عناصر از فایل‌ها: مقداری که با \f[C]\[at]\f[R] آغاز شود به صورت متن خام خوانده می‌شود، در حالی که اگر با یک \f[C]%\f[R] شروع شود، به شکل base64 کُدگذاری خواهد شد و اگر با \f[C]:\f[R] آغاز گردد محتویات آن به عنوان JSON تفسیر می‌شود: .IP .nf \f[C] $ jo program=jo authors=\[at]AUTHORS {\[dq]program\[dq]:\[dq]jo\[dq],\[dq]authors\[dq]:\[dq]Jan-Piet Mens \[dq]} $ jo filename=AUTHORS content=%AUTHORS {\[dq]filename\[dq]:\[dq]AUTHORS\[dq],\[dq]content\[dq]:\[dq]SmFuLVBpZXQgTWVucyA8anBtZW5zQGdtYWlsLmNvbT4K\[dq]} $ jo nested=:nested.json {\[dq]nested\[dq]:{\[dq]field1\[dq]:123,\[dq]field2\[dq]:\[dq]abc\[dq]}} \f[R] .fi.PP برای جلوگیری از تفسیر شدن، می‌توان این نویسه‌ها را گریزدهی (escape) کرد: .IP .nf \f[C] $ jo name=\[dq]JP Mens\[dq] twitter=\[aq]\[rs]\[at]jpmens\[aq] {\[dq]name\[dq]:\[dq]JP Mens\[dq],\[dq]twitter\[dq]:\[dq]\[at]jpmens\[dq]} $ jo char=\[dq] \[dq] URIescape=\[rs]\[rs]%20 {\[dq]char\[dq]:\[dq] \[dq],\[dq]URIescape\[dq]:\[dq]%20\[dq]} $ jo action=\[dq]split window\[dq] vimcmd=\[dq]\[rs]:split\[dq] {\[dq]action\[dq]:\[dq]split window\[dq],\[dq]vimcmd\[dq]:\[dq]:split\[dq]} \f[R] .fi .PP خواندن مقادیر عناصر از یک فایل به‌منظور غلبه بر محدودیت‌های ARG_MAX هنگام انتساب شیء: .IP .nf \f[C] $ ls | jo -a > child.json $ jo files:=child.json {\[dq]files\[dq]:[\[dq]AUTHORS\[dq],\[dq]COPYING\[dq],\[dq]ChangeLog\[dq] .... $ ls *.c | jo -a > source.json; ls *.h | jo -a > headers.json $ jo -a :source.json :headers.json [[\[dq]base64.c\[dq],\[dq]jo.c\[dq],\[dq]json.c\[dq]],[\[dq]base64.h\[dq],\[dq]json.h\[dq]]] \f[R] .fi .PP افزودن عناصر به JSON موجود: .IP .nf \f[C] $ jo -f source.json 1 | jo -f - 2 3 [\[dq]base64.c\[dq],\[dq]jo.c\[dq],\[dq]json.c\[dq],1,2,3] $ curl -s \[aq]https://noembed.com/embed?url=https://www.youtube.com/watch?v=dQw4w9WgXcQ\[aq] | jo -f - status=Rickrolled { ...., \[dq]type\[dq]:\[dq]video\[dq],\[dq]author_url\[dq]:\[dq]https://www.youtube.com/user/RickAstleyVEVO\[dq],\[dq]status\[dq]:\[dq]Rickrolled\[dq]} \f[R] .fi .PP حذف کلیدهای تکراری شیء (\f[I]jo\f[R] به‌طور پیش‌فرض کلیدهای تکراری شیء را ضمیمه می‌کند): .IP .nf \f[C] $ jo a=1 b=2 a=3 {\[dq]a\[dq]:1,\[dq]b\[dq]:2,\[dq]a\[dq]:3} $ jo -D a=1 b=2 a=3 {\[dq]a\[dq]:3,\[dq]b\[dq]:2} \f[R] .fi .SH "گزینه‌ها (OPTIONS)" .PP دستور \f[I]jo\f[R] گزینه‌های سراسری زیر را می‌شناسد. .TP -a فهرست \f[I]words\f[R] را به‌صورت مقادیر آرایه تفسیر می‌کند و به‌جای یک شیء، یک آرایه تولید می‌کند. .TP -B به‌طور پیش‌فرض، \f[I]jo\f[R] رشته‌های \[lq]\f[C]true\f[R]\[rq] و \[lq]\f[C]false\f[R]\[rq] را به‌ترتیب به‌عنوان عناصر بولی \f[C]true\f[R] و \f[C]false\f[R]، و \[lq]\f[C]null\f[R]\[rq] را به‌صورت \f[C]null\f[R] تفسیر می‌کند. با این گزینه، این رفتار را غیرفعال کنید. .TP -D حذف کلیدهای تکراری شیء. .TP -e نادیده گرفتن \f[I]stdin\f[R] خالی (یعنی زمانی که \f[I]stdin\f[R] خالی است، خطای تشخیصی صادر نشود). .TP -n کلیدهای دارای مقادیر خالی اضافه نشوند. .TP -p قالب‌بندی زیبا و خوانا (Pretty-print) رشتهٔ JSON در خروجی به‌جای خروجی مختصر یک‌خطی که به‌طور پیش‌فرض چاپ می‌شود. .TP -v نمایش نسخه و خروج. .TP -V نمایش نسخه در قالب یک شیء JSON و خروج..SH "گزارش باگ‌ها (BUGS)" .PP احتمالاً وجود دارند. .PP اگر مقداری که به \f[I]jo\f[R] داده می‌شود در شل به یک مقدار خالی بسط یابد، آن‌گاه \f[I]jo\f[R] در حالت شیء مقدار \f[C]null\f[R] تولید می‌کند، و ممکن است به نظر برسد در حالت آرایه معلق شده است؛ برنامه معلق نشده، بلکه در حال خواندن از \f[I]stdin\f[R] است. این یک باگ نیست. .PP مقادیر عددی به عدد تبدیل می‌شوند که می‌تواند نتایج ناخواسته‌ای به همراه داشته باشد. اگر یک مقدار عددی را درون نقل‌قول قرار دهید، \f[I]jo\f[R] آن را به یک رشته تبدیل می‌کند. موارد زیر را مقایسه کنید: .IP .nf \f[C] $ jo a=1.0 {\[dq]a\[dq]:1} $ jo a=\[rs]\[dq]1.0\[rs]\[dq] {\[dq]a\[dq]:\[dq]1.0\[dq]} \f[R] .fi .PP از قلم انداختن براکت پایانی در یک عنصر تو‌در‌تو باعث چاپ یک پیام تشخیصی می‌شود، اما خروجی در هر صورت حاوی داده‌های نامعتبر خواهد بود. این رفتار عمداً به این شکل طراحی شده است. .SH "وضعیت خروج (EXIT STATUS)" .PP برنامهٔ \f[I]jo\f[R] در صورت موفقیت با کد 0 و در صورت شکست، پس از مشخص کردن دلیل بروز خطا، با مقداری غیر صفر خارج می‌شود. .SH "در دسترس بودن (AVAILABILITY)" .PP .SH "قدردانی‌ها (CREDITS)" .IP \[bu] 2 این برنامه از \f[C]json.[ch]\f[R]، اثر Joseph A. Adams استفاده می‌کند. .SH "همچنین ببینید (SEE ALSO)" .IP \[bu] 2 .IP \[bu] 2 .IP \[bu] 2 .IP \[bu] 2 strtod(3) .SH "نویسندگان (AUTHORS)" .PP Jan-Piet Mens