JSON থেকে YAML কমান্ড-লাইন: একটি yq কমান্ডের আড়ালে চারটি ফাঁদ
সংক্ষেপে: টিউটোরিয়ালে সবচেয়ে বেশি কপি করা কমান্ড yq -P input.json > output.yaml আসলে yq v4-এ JSON-ই আউটপুট দেয়। yq v4.44.6, PyYAML 6.0.3 ও js-yaml দিয়ে 2.39 MB নমুনায় চার সেট পরিমাপ থেকে দেখানো হয়েছে যে আউটপুট ফরম্যাট ইনপুট এক্সটেনশনের হাতে, আর ব্যাচ রূপান্তর, উদ্ধৃতি, ইনডেন্টেশন ও বড় পূর্ণসংখ্যার নির্ভুলতার সঠিক লেখনীও দেওয়া হয়েছে।

সারাংশ: বাংলা ও ইংরেজি টিউটোরিয়ালে সবচেয়ে বেশি দেখা যায় এমন yq -P input.json > output.yaml, yq v4-এর উপর আসলে JSON-ই তৈরি করে। YAML পেতে হলে -o=yaml (অথবা -oy) স্পষ্ট করে লিখতে হবে; -P হলো --prettyPrint-এর সংক্ষিপ্ত রূপ, যা ইনডেন্টেশন ও ব্লক স্টাইল নিয়ন্ত্রণ করে, আউটপুট ফরম্যাট নয়।
JSON-কে YAML-এ বদলানো কখনোই "ফাইলের এক্সটেনশন পাল্টানো"র মতো সহজ কাজ ছিল না। আসল খরচ লুকিয়ে আছে চার জায়গায়: আউটপুট ফরম্যাট ঠিক করে ইনপুট এক্সটেনশন, উদ্ধৃতির নিয়ম চুপিচুপি আপনার স্ট্রিং বদলে দেয়, সিকোয়েন্স ইনডেন্টেশন নিচের ধাপের টুলকে প্রভাবিত করে, আর yq-এর মধ্য দিয়ে যাওয়া একটি বড় পূর্ণসংখ্যা চিরতরে নির্ভুলতা হারায়।
১. আগে সেই সবচেয়ে জনপ্রিয় কমান্ডটি একবার চালিয়ে দেখি
একটি পরিষ্কার মেশিনে yq v4.44.6 ইনস্টল করে একটি ক্ষুদ্রতম ইনপুট বানাই:
printf '{"a":1,"b":{"c":2}}' > s.json
yq -P '.' s.json
যা ফেরত আসে তা YAML নয়, বরং ইনডেন্ট করা JSON:
{
"a": 1,
"b": {
"c": 2
}
}
টিউটোরিয়াল মেনে এই কমান্ডটি output.yaml-এ রিডাইরেক্ট করলে আপনি পাবেন একটি .yaml এক্সটেনশনের ফাইল যার ভেতরে JSON। প্রতিটি YAML 1.2 পার্সার এটি খুশি মনে পড়ে ফেলে (YAML 1.2-এ JSON একটি সাবসেট — এই অন্তর্ভুক্তির পুরো যুক্তি JSON, YAML ও XML রূপান্তরের সীমানা-তে বিস্তারিত আছে), তাই সাথে সাথে কোনো এরর আসবে না — যেদিন কেউ এতে কমেন্ট বা অ্যাঙ্কর যোগ করবে, অথবা CI-এর yamllint একগাদা truthy value should be one of ছুড়তে শুরু করবে, সেদিন খোঁজাখুঁজি শুরু হবে।
সত্যিকারের YAML তৈরি করে এমন লেখনী হলো আউটপুট ফরম্যাট স্পষ্ট করে দেওয়া:
yq -o=yaml '.' s.json
# a: 1
# b:
# c: 2
২. কেন এমন হয়: এক্সটেনশন আউটপুট ফরম্যাট ঠিক করে
yq v4-এর নিয়ম হলো "ইনপুট ফরম্যাট আউটপুট ফরম্যাট ঠিক করে"। এটি ইনপুট ফাইলের এক্সটেনশন দেখে ফরম্যাট অনুমান করে, আর -o না থাকলে সেই অনুমানই ধরে রাখে। .json ইনপুট → JSON আউটপুট; .yaml ইনপুট → YAML আউটপুট; stdin থেকে পড়ার সময় কোনো এক্সটেনশন না থাকলে ডিফল্ট YAML।
একই ইনপুটে চারটি লেখনীর পরিমাপকৃত ফলাফল:
| কমান্ড | ইনপুট উৎস | প্রকৃত আউটপুট ফরম্যাট | ফলাফল |
|---|---|---|---|
yq -P '.' s.json |
s.json ফাইল |
JSON (ইনডেন্ট সহ) | .yaml-এ ফেললে ফাঁদ |
yq -o=yaml '.' s.json |
s.json ফাইল |
YAML (ব্লক স্টাইল) | সঠিক |
yq -P -o=yaml '.' s.json |
s.json ফাইল |
YAML (ব্লক স্টাইল) | সঠিক, এখানে -P অপ্রয়োজনীয় |
cat s.json | yq -P '.' |
stdin, কোনো এক্সটেনশন নেই | YAML (ব্লক স্টাইল) | সঠিক, কারণ ডিফল্ট yaml |
তৃতীয় সারি একটি কথা বলে: -o=yaml থাকতে -P সবসময় দরকার হয় না, কিন্তু তা নিরীহও নয় — ষষ্ঠ ভাগের সময়ের পরিমাপ দেখুন। চতুর্থ সারি বোঝায় "টিউটোরিয়াল কপি করেই আমার কাজ হয়ে গেল" কেন: অনেকে পাইপ দিয়ে ডেটা খাওয়ায়, যা কাকতালীয়ভাবে এক্সটেনশন শাখাটিকে এড়িয়ে যায়।
এই আচরণের ব্যবহারিক তাৎপর্য আরেকটু খুলে বলা যায়। আপনি যদি একটি রিপোজিটরিতে configs/prod.json আর configs/base.yaml একসঙ্গে রাখেন, তবে একই yq '.' কমান্ড দুটি ফাইলে ভিন্ন ফরম্যাটের আউটপুট দেবে। কেউ যদি সেই আউটপুটকে আবার রিপোজিটরিতে কমিট করে, তবে diff-এ মিশ্রণ দেখা যাবে: একটি ফাইল JSON স্টাইলে, অন্যটি YAML স্টাইলে। সমাধান সহজ — প্রতিটি কমান্ডে -o স্পষ্ট করে লিখুন, অনুমানের উপর নির্ভর করবেন না।
৩. ব্যাচ রূপান্তর: তিনটি শেল পদ্ধতি
একটি ফাইল রূপান্তর তো শুরু মাত্র। কমান্ড-লাইনে এই কাজের আসল প্রয়োজন প্রায় সবসময়ই ব্যাচ: একটি ডিরেক্টরির সব কনফিগারেশন, সব API স্ন্যাপশট একবারে YAML-এ বদলানো।
bash / zsh লুপ (সবচেয়ে সরাসরি, এক ডিরেক্টরির জন্য):
for f in configs/*.json; do
yq -o=yaml '.' "$f" > "${f%.json}.yaml"
done
find দিয়ে রিকার্সিভ (সাবডিরেক্টরিও লাগলে):
find . -name '*.json' -exec sh -c 'yq -o=yaml "." "$1" > "${1%.json}.yaml"' _ {} \;
PowerShell (Windows CI-তে):
Get-ChildItem *.json | ForEach-Object { yq -o=yaml '.' $_.FullName > ($_.BaseName + '.yaml') }
তিনটি লেখনীরই একটি কঠিন পূর্বশর্ত আছে: আগে নিশ্চিত হোন উৎস JSON বৈধ। রূপান্তরকারী আর পার্সার এক নয়; সিনট্যাক্স ভুল পেলে অনেক রূপান্তরকারী শুধু একটা অস্পষ্ট অবস্থান দেয়, লাইন নম্বরসহ বিস্তারিত দেয় না যেমনটা একটি ভ্যালিডেটর দেয়। লুপের ভেতরে এক লাইনের গার্ড বসানোর খরচ প্রায় শূন্য:
for f in configs/*.json; do
jq empty "$f" || { echo "invalid: $f"; continue; }
yq -o=yaml '.' "$f" > "${f%.json}.yaml"
done
jq empty শুধু পার্স করে, কিছু প্রিন্ট করে না; অবৈধ JSON-এ নন-জিরো এক্সিট কোড দেয়। set -euo pipefail-এর সাথে মিলিয়ে পুরো পাইপলাইন প্রথম খারাপ ফাইলেই থেমে যাবে, অর্ধেক-তৈরি আউটপুটের স্তূপ ফেলবে না।
খেয়াল রাখার মতো আরেকটি বিষয়: for f in configs/*.json লুপটি ফাইলের নামে স্পেস থাকলে নিরাপদ, কারণ "$f" কোট করা আছে; কিন্তু কোনো ফাইল মেলে না তবে গ্লোব আক্ষরিকভাবে configs/*.json হিসেবে লুপে ঢুকে পড়ে। বড় রিপোজিটরিতে shopt -s nullglob অথবা find-ভিত্তিক লেখনী বেছে নেওয়াই নিরাপদ।
৪. চারটি আউটপুট প্যারামিটার, চারটি আলাদা কাজ
yq-এর প্যারামিটার তালিকা লম্বা, কিন্তু JSON → YAML পথে আসলে মনে রাখার মতো মাত্র চারটি:
| প্যারামিটার | কাজ | কখন অবশ্যই লিখতে হবে |
|---|---|---|
-o=yaml / -oy |
আউটপুট ফরম্যাট YAML নির্ধারণ | ইনপুট .json ফাইল হলে |
-P / --prettyPrint |
ব্লক স্টাইল জোর করে, ইনডেন্টেশন নিয়মিত করে | stdin থেকে পড়লে, অথবা সিকোয়েন্স ইনডেন্টেশন দরকার হলে |
-I=n |
ইনডেন্টেশনের স্পেস সংখ্যা, ডিফল্ট 2 | নিচের ধাপ 4 স্পেস চাইলে (যেমন কিছু Ansible স্টাইল গাইড) |
--split-exp |
অ্যারের উপাদানগুলোকে আলাদা ডকুমেন্টে ভাগ করে | Kubernetes মাল্টি-রিসোর্স ম্যানিফেস্ট তৈরিতে |
মাল্টি-ডকুমেন্ট বিষয়টি আলাদাভাবে বলার যোগ্য। Kubernetes ম্যানিফেস্টে প্রথা হলো --- দিয়ে একাধিক রিসোর্স আলাদা করা। JSON অ্যারে থেকে তৈরি করতে:
yq -P -o=yaml '.[] | splitDoc' --split-exp 'true' kubernetes-list.json
--split-exp না দিলে একটি YAML সিকোয়েন্স পাবেন; দিলে প্রতিটি অ্যারে উপাদান --- দিয়ে আলাদা করা স্বতন্ত্র ডকুমেন্ট হয়। দুটি ফাইলই kubectl apply খেতে পারে, কিন্তু diff-এর পঠনীয়তায় এক ধাপ তফাত।
৫. উদ্ধৃতি: ছয় ধরনের স্ট্রিং যেখানে উদ্ধৃতি বাধ্যতামূলক
YAML-এর টাইপ অনুমান অন্তর্নিহিত। কোনো স্ট্রিং মান যদি সংখ্যা বা বুলিয়ানের মতো দেখতে হয়, উদ্ধৃতি না থাকলে তা অন্য টাইপে পার্স হবে। এটি তাত্ত্বিক ঝুঁকি নয় — yq v4.44.6-এ পরিমাপ করে দেখা গেছে নিচের ছয় ধরনের মানে স্বয়ংক্রিয়ভাবে উদ্ধৃতি বসে যায়, যা প্রমাণ করে যে পার্সার সত্যিই সেগুলোকে ভুল পড়তে পারত:
printf '{"version":"1.0","enabled":"true","port":"8080","empty":"","colon":"host: value","hash":"v # c","unicode":"端口 8080","ts":"2026-11-03"}' | yq -P -o=yaml '.'
version: "1.0"
enabled: "true"
port: "8080"
empty: ""
colon: 'host: value'
hash: 'v # c'
unicode: 端口 8080
ts: "2026-11-03"
এক এক করে পরিণতি:
| মূল মান (JSON স্ট্রিং) | উদ্ধৃতি না থাকলে কী হিসেবে পড়া হবে | বাস্তব প্রভাব |
|---|---|---|
"1.0" |
ফ্লোট 1.0 |
ভার্সন নম্বর দশমিক হয়ে যায়, 1.10 বনে 1.1 |
"true" |
বুলিয়ান true |
শর্তমূলক যুক্তি উল্টে যায় বা টাইপ মেলে না |
"8080" |
পূর্ণসংখ্যা 8080 |
পোর্টের টাইপ বদলে যায়, স্ট্রিং তুলনা ব্যর্থ হয় |
"" |
null |
খালি স্ট্রিং মিলিয়ে যায়, নিচের ধাপ None পায় |
"host: value" |
পার্স এরর অথবা নেস্টেড ম্যাপিং | কোলনের পর স্পেস থাকতেই হবে, নাহলে সিনট্যাক্স ভুল |
"2026-11-03" |
তারিখ অবজেক্ট | স্ট্রিং নয়, datetime.date হিসেবে ডিসিরিয়ালাইজ হয় |
শেষেরটি সবচেয়ে বিপজ্জনক। JSON-এ তারিখ মানে একটি স্ট্রিং; রূপান্তরের পর তা YAML-এর তারিখ টাইপে বদলে যায়, আর অনেক মডেল সেটিকে ফেরত দেওয়ার সময় মূল স্ট্রিং নয়, ISO ফরম্যাটের তারিখ অবজেক্ট দেয় — রাউন্ড-ট্রিপ সামঞ্জস্যতা ছিঁড়ে যায়। PyYAML ও yq দুটোই এই মানগুলোতে উদ্ধৃতি জুড়ে দেয়, যেন স্বীকার করে নেয় ঝুঁকিটা বাস্তব।
এক পাশে লক্ষ্য করুন, unicode: 端口 8080 লাইনে কোনো উদ্ধৃতি নেই — চীনা (এবং বাংলা) অক্ষর YAML-এ নিরাপদ। চিন্তার বিষয় সেটি নয়, বরং পরের ভাগের কি-ক্রম ও নির্ভুলতা। তবে একটি সতর্কতা আছে: আপনার এডিটর বা টার্মিনাল যদি এনকোডিং ঠিকমতো না ধরে, তবে বহুভাষিক স্ট্রিং নিয়ে কাজ করার সময় অদ্ভুত আচরণ দেখা যেতে পারে — সবসময় LANG-এ UTF-8 নিশ্চিত করুন।
৬. Python ও Node-এর সমতুল্য লেখনী এবং পরিমাপকৃত সময়
প্রতিটি মেশিনে yq ইনস্টল করা যায় না (অফলাইন পরিবেশ, সীমাবদ্ধ CI ইমেজ, প্যাকেজ ম্যানেজারবিহীন Windows)। Python ও Node-এর সমতুল্য লেখনীর নিজস্ব ডিফল্ট ফাঁদ আছে। তিনটি পথ কোন পরিস্থিতিতে বেছে নেবেন, তার পুরো তুলনামূলক সারণি JSON কমান্ড-লাইন টুল ও এডিটর নির্বাচন-এ আছে; এই নিবন্ধ কেবল JSON → YAML দিকটিতেই সীমাবদ্ধ।
Python + PyYAML (তিনটি আর্গুমেন্ট, কোনোটিই ঐচ্ছিক নয়):
import json, yaml
with open("config.json", encoding="utf-8") as f:
data = json.load(f)
with open("config.yaml", "w", encoding="utf-8") as f:
yaml.safe_dump(
data, f,
default_flow_style=False, # ব্লক স্টাইল, {a: 1, b: 2} নয়
allow_unicode=True, # বাংলা/চীনা \u09AC\u0982-এ এস্কেপ হবে না
sort_keys=False, # JSON-এর মূল কি-ক্রম বজায় থাকে
)
এই তিনটির ডিফল্ট হলো False / False / True, অর্থাৎ বাক্স থেকে বেরিয়ে আসা PyYAML কিগুলোকে বর্ণানুক্রমে সাজিয়ে দেয় এবং বাংলা-চীনাকে \uXXXX-এ পাল্টে দেয়। একই ইনপুটে ডিফল্ট প্যারামিটারে আউটপুট:
apiVersion: v1
data:
LOG_LEVEL: info
colon: 'host: value'
unicode: "\u7AEF\u53E3 8080"
kind: ConfigMap
metadata:
labels:
app: web
name: app-config
খেয়াল করুন kind চলে গেছে apiVersion-এর পরে, metadata-এর আগে — Kubernetes ম্যানিফেস্টে apiVersion-কে kind-এর আগে রাখা সম্প্রদায়ের প্রথা; কি-ক্রম নষ্ট হলে পার্সিং ভাঙে না ঠিকই, কিন্তু রিভিউ করা লোকের জন্য তা অস্বস্তিকর।
Node + js-yaml:
const fs = require("fs");
const yaml = require("js-yaml");
const data = JSON.parse(fs.readFileSync("config.json", "utf8"));
fs.writeFileSync(
"config.yaml",
yaml.dump(data, { lineWidth: -1, noRefs: true, sortKeys: false })
);
lineWidth: -1 লম্বা লাইনের ফোল্ডিং বন্ধ করে (নাহলে লম্বা URL মাঝখান থেকে ভেঙে যায়), noRefs: true অ্যাঙ্কর ও অ্যালিয়াস তৈরি নিষিদ্ধ করে (নিচের ধাপ kubectl হলে অবশ্যই বন্ধ করতে হবে, কিছু টুল অ্যাঙ্কর পাত্তা দেয় না)।
পরিমাপকৃত সময় (নমুনা: 2.39 MB JSON, 12000টি রেকর্ড, প্রতিটিতে একটি নেস্টেড অবজেক্ট ও দুটি অ্যারে; মেশিন হলো এই কাজের জন্য ব্যবহৃত স্যান্ডবক্স):
| বাস্তবায়ন | রূপান্তরের সময় | উল্টো পার্সের সময় | রাউন্ড-ট্রিপ |
|---|---|---|---|
yq -o=yaml v4.44.6 |
0.45 s | 0.45 s | সামঞ্জস্যপূর্ণ |
yq -P -o=yaml v4.44.6 |
4.16 s | — | সামঞ্জস্যপূর্ণ |
| Node js-yaml 4.x | 0.23 s | 0.11 s | সামঞ্জস্যপূর্ণ |
| Python PyYAML 6.0.3 | 3.26 s | 8.01 s | সামঞ্জস্যপূর্ণ |
দুটি স্ববিরোধী ফলাফল। প্রথমত, -P যোগ করলে yq প্রায় 9 গুণ ধীর হয়ে যায় (0.45 s → 4.16 s), অথচ এই নমুনায় আউটপুটের বাইট সংখ্যা হুবহু একই (দুই ক্ষেত্রেই 2,326,895 বাইট) — -P আসলে একটা পূর্ণ পুনর্বিন্যাস পাস চালায়, যার দাম কম নয়, তাই ব্যাচে কয়েকশো ফাইল রূপান্তরের সময় বাঁচানো সম্ভব হলে বাঁচান। দ্বিতীয়ত, PyYAML-এর উল্টো পার্স (8.01 s) তার সামনের রূপান্তরের (3.26 s) চেয়ে দ্বিগুণেরও বেশি ধীর; আপনার পাইপলাইন বারবার YAML ফেরত পড়লে Python ভালো পছন্দ নয়।
আরেকটি তথ্য: 2.39 MB JSON ব্লক স্টাইল YAML-এ বদলালে দাঁড়ায় 2.33 MB, অর্থাৎ প্রায় 3% ছোট। প্রচলিত কথা "YAML সবসময় JSON-এর চেয়ে বড়" সত্য নয় — গভীর নেস্টিংয়ে JSON-এর উদ্ধৃতি, কমা ও কার্লি ব্রেস যে জায়গা নেয়, তা YAML-এর ইনডেন্টেশনের ফাঁকা স্পেসের চেয়ে বেশি হতে পারে।
৭. যে তিনটি জিনিস ফেরত আসে না
আগের ভাগগুলো বলেছে "কীভাবে ঠিক করে রূপান্তর করবেন"। এই ভাগ বলে "কী হারিয়ে যায়"। বিশেষভাবে বানানো একটি ইনপুট দিয়ে পরিমাপ:
printf '{"order_id":12345678901234567890,"zip":"0150","ts":"2026-11-03","f":1.0e6}' > t.json
yq -o=yaml '.' t.json
yq-এর আউটপুট:
order_id: 1.2345678901234567e+19
zip: "0150"
ts: "2026-11-03"
f: 1000000
আবার JSON-এ ফেরালে: {"order_id":12345678901234567000,"zip":"0150","ts":"2026-11-03","f":1000000}।
20 অঙ্কের অর্ডার আইডি 12345678901234567890 বদলে গিয়ে 12345678901234567000 হয়েছে — শেষ তিন অঙ্ক শূন্য, আর কোনো সতর্কতাই নেই। কারণ yq Go-এর float64 পার্স পথে যায়; 2^53-এর বড় পূর্ণসংখ্যা নিখুঁতভাবে প্রকাশ করা যায় না, তাই এটি বৈজ্ঞানিক নোটেশনে আউটপুট দেয় এবং ফেরত আসার সময় মূল মান আর ফেরে না।
একই ইনপুট PyYAML-এ দিলে:
order_id: 12345678901234567890
zip: '0150'
ts: '2026-11-03'
f: 1000000.0
Python-এর পূর্ণসংখ্যা যেকোনো নির্ভুলতার, তাই 20 অঙ্কই অক্ষুণ্ণ থাকে এবং ফেরত পড়লেও 12345678901234567890 পাওয়া যায়। আপনার ডেটায় অর্ডার আইডি, স্নোফ্লেক আইডি বা জাতীয় পরিচয় নম্বরের মতো লম্বা সংখ্যা থাকলে yq ব্যবহার করবেন না, Python ব্যবহার করুন, অথবা আগেই ফিল্ডটিকে স্ট্রিং বানিয়ে ফেলুন। এই ধরনের নির্ভুলতা সমস্যার পুরো কার্যপ্রণালী JSON-এ বড় পূর্ণসংখ্যার নির্ভুলতা কেন নষ্ট হয়-এ বিস্তারিত আছে।
দ্বিতীয় যা হারায় তা হলো float ও int-এর পার্থক্য: 1.0e6 yq-এর আউটপুটে 1000000 (পূর্ণসংখ্যা) হয়, PyYAML 1000000.0 রাখে। তৃতীয় হলো কি-ক্রম — PyYAML ডিফল্টভাবে সাজায়, yq ও js-yaml ডিফল্টভাবে রাখে; ভিন্ন ভাষার দল একসঙ্গে কাজ করলে এটি একটি লুক্কায়িত মতভেদের উৎস।
বাস্তব প্রকল্পে এই তিনটির মধ্যে সবচেয়ে ক্ষতিকর প্রথমটি, কারণ এটি নীরব। অর্ডার আইডি, ট্রানজেকশন আইডি, স্নোফ্লেক আইডি — এগুলোর শেষ কয়েক অঙ্ক বদলে গেলেও ফাইলটি দেখতে একেবারে ঠিকঠাক মনে হয়। তাই রূপান্তরের আগে একটি ছোট নমুনা সেটে রাউন্ড-ট্রিপ যাচাই চালানো মানেই ভবিষ্যতের ঘণ্টার পর ঘণ্টা ডিবাগিং বাঁচানো।
৮. CI-তে শুধু convert করবেন না: যাচাই → রূপান্তর → lint
রূপান্তরকেই একমাত্র ধাপ ভাবা সবচেয়ে সাধারণ পাইপলাইন ত্রুটি। রূপান্তর সফল হলে এক্সিট কোড 0 আসে, যার অর্থ কেবল "ইনপুট JSON পার্স হলো" — এর মানে এই নয় যে আউটপুট সঠিক, বা আউটপুট নিচের ধাপের দাবি মেটায়। সঠিক তিন-ধাপ কাঠামো:
#!/usr/bin/env bash
set -euo pipefail
# 1. উৎস যাচাই: সিনট্যাক্স স্তর
jq empty deployment.json
# 2. রূপান্তর: আউটপুট ফরম্যাট স্পষ্ট করে দিন
yq -o=yaml '.' deployment.json > deployment.yaml
# 3. ফলাফল যাচাই: YAML পার্সার পড়তে পারছে, আর লিন্ট পরিষ্কার
yq -o=json -I=0 '.' deployment.yaml > /dev/null
yamllint deployment.yaml
৩ নম্বর ধাপের সেই yq -o=json ... > /dev/null লাইনটি দেখতে অপ্রয়োজনীয় মনে হয়, কিন্তু বাস্তবে পুরো ব্লকের সবচেয়ে দরকারি লাইন: এটি ফলাফলকে জোর করে আবার পার্স করায়। ইনডেন্টেশন ভুল, অ্যাঙ্কর রিজলিউশন ব্যর্থতা, টাইপ বদলে যাওয়া — সব এই ধাপেই ধরা পড়ে। এটি এড়িয়ে গেলে সমস্যা kubectl apply বা অ্যাপ চালুর সময় গিয়ে ফাটবে।
ফলাফলে যদি মানুষের রক্ষণাবেক্ষণ করা কনফিগারেশন হয় (Helm values, Docker Compose, GitHub Actions ওয়ার্কফ্লো), তবে আরও তিনটি বিষয় নিশ্চিত করুন: কি-ক্রম নষ্ট হয়নি তো, লম্বা সংখ্যার নির্ভুলতা টিকে আছে তো, আর কমেন্ট কি হাতে যোগ করতে হবে — JSON-এ কমেন্ট নেই, যেকোনো টীকা রূপান্তরের পরেই লিখতে হবে, কোনো রূপান্তরকারী তা আপনার হয়ে তৈরি করবে না।
সাধারণ প্রশ্ন
yq -P আর -o=yaml, আসলে কোনটি লিখব?
-o=yaml ঠিক করে "আউটপুট YAML কি না", -P ঠিক করে "YAML দেখতে কেমন"। ইনপুট .json ফাইল হলে -o=yaml বাধ্যতামূলক; -P তখনই লাগবে যখন ব্লক স্টাইল বা সিকোয়েন্স ইনডেন্টেশন জোর করে চাই। stdin থেকে পড়ার সময় কোনো এক্সটেনশন নেই, সেখানে yq ডিফল্টভাবে YAML দেয়, তাই -P একাই যথেষ্ট।
রূপান্তরিত YAML সরাসরি Kubernetes-এ দেওয়া যাবে?
সিনট্যাক্সের দিক থেকে যাবে, তবে তিনটি শর্ত সহ: নিশ্চিত করুন apiVersion-এর মতো ক্রম-প্রথাযুক্ত কি সাজানো হয়নি (PyYAML ডিফল্টভাবে সাজায়, sort_keys=False দিতে হবে), নিশ্চিত করুন কোনো অ্যাঙ্কর বা অ্যালিয়াস তৈরি হয়নি (js-yaml-এ noRefs: true দিতে হবে), আর নিশ্চিত করুন লম্বা সংখ্যার নির্ভুলতা টিকে আছে। মাল্টি-রিসোর্স ম্যানিফেস্টের ক্ষেত্রে --split-exp দিয়ে ----দ্বারা পৃথক ডকুমেন্টে ভাগ করতে হবে।
আমার রূপান্তরিত YAML এক লাইনের {a: 1, b: 2}, ইনডেন্টেড নয় কেন?
এটি ফ্লো স্টাইল; বৈধ ঠিকই, কিন্তু রূপান্তরের উদ্দেশ্যই নষ্ট করে দেয়। -P দিয়ে ব্লক স্টাইল জোর করুন; PyYAML ব্যবহার করলে নিশ্চিত করুন default_flow_style=False (PyYAML 5.1 থেকে ডিফল্ট মান False, পুরোনো ভার্সনে স্পষ্ট করে লিখতে হয়)।
20 অঙ্কের অর্ডার আইডি YAML-এ গিয়ে শেষের অঙ্কগুলো 0 হয়ে গেল, বাঁচানো যায়?
ফেরত পাওয়া যায় না, কেবল আগে থেকে আটকানো যায়। yq float64 দিয়ে পার্স করে, তাই 2^53-এর বড় পূর্ণসংখ্যার নির্ভুলতা গঠনগতভাবেই যায়। হয় Python-এ যান (পূর্ণসংখ্যা যেকোনো নির্ভুলতার; পরিমাপে অক্ষুণ্ণ প্রমাণিত), নাহলে JSON-েই লম্বা সংখ্যা স্ট্রিং হিসেবে রাখুন — দ্বিতীয়টি বেশি নিরাপদ, কারণ এটি JavaScript দিকের JSON.parse-এর একই সমস্যাও একসাথে মিটিয়ে দেয়।
অনলাইন রূপান্তর টুল না কমান্ড-লাইন?
গোপনীয় কনফিগারেশন, টোকেন-সহ API স্ন্যাপশট — লোকাল কমান্ড-লাইন বা পিওর ফ্রন্টএন্ড টুল ব্যবহার করুন, আপলোড করবেন না। একবারের, ছোট ভলিউমের, চোখে দেখে নিশ্চিত হতে চাইলে অনলাইন টুল দ্রুত; এই সাইটের /convert/yaml ব্রাউজারেই চলে, ডেটা মেশিন থেকে বের হয় না। ব্যাচ, CI-তে ঢোকানো, পুনরুৎপাদনযোগ্য — এগুলোর জন্য সবসময় কমান্ড-লাইন, আর যাচাইয়ের ধাপগুলো একই স্ক্রিপ্টে লিখে রাখুন।