我有一個包含以下內容的 json 檔案 test.json:
[
{
"name": "Akshay",
"id": "234"
},
{
"name": "Amit",
"id": "28"
}
]
我有一個包含內容的 shell 腳本:
#!/bin/bash
function display
{
echo "name is $1 and id is $2"
}
cat test.json | jq '.[].name,.[].id' | while read line; do display $line; done
我希望將單個專案的名稱和 ID 作為引數一起傳遞給函式顯示,但輸出是這樣的:
name is "Akshay" and id is
name is "Amit" and id is
name is "234" and id is
name is "28" and id is
實作代碼的正確方法應該是什么?PS:我特別想使用 jq 所以請根據 jq 來回答
uj5u.com熱心網友回復:
兩個主要問題,以及一些對您當前的示例用例可能無關緊要但在您處理來自不受信任來源的真實資料時可能很重要的附加專案:
- 您當前的代碼在撰寫任何s之前迭代所有 s。
nameid - 您當前的代碼使用換行符分隔符,但沒有努力將多行讀入每個
while回圈迭代。 - 您的代碼使用換行符分隔符,但換行符可以出現在字串中;因此,這限制了輸入域。
- 當您通過管道進入
while回圈時,該回圈在子shell中運行;當管道退出時,子外殼也會退出,因此回圈設定的任何變數都會丟失。 - 與直接讀取相比,啟動副本
/bin/cat并jq從其輸出讀取管道是愚蠢且低效的。jqtest.json
我們可以解決所有這些問題:
- 要成對寫
names 和ids,你會想要更像jq '.[] | (.name, .id)' - 要讀取回圈中每個元素的名稱和 id,您需要
while IFS= read -r name && IFS= read -r id; do ...遍歷這些對。 - 要從換行符切換到 NUL(NUL 是唯一不能存在于 C 字串或 bash 字串中的字符),您需要使用 to 的
-j引數jq,然后將顯式"\u0000"元素添加到正在寫入的內容中. 要在 bash 端讀取此 NUL 分隔的內容,您需要將-d ''引數添加到每個read. - 要將
while read回圈移出子shell,我們可以使用行程替換,如BashFAQ #24 中所述。 - 要
jq直接從 讀取test.json,請使用讓<test.jsonshell 將檔案直接連接到 jq 的標準輸入,或在 jq 的命令列上傳遞檔案名。
針對包含 JSON 編碼 NUL 的輸入資料,以穩健的方式執行上述所有操作,如下所示:
#!/bin/bash
display() {
echo "name is $1 and id is $2"
}
cat >test.json <<'EOF'
[
{ "name": "Akshay", "id": "234" },
{ "name": "Amit", "id": "28" }
]
EOF
while IFS= read -r -d '' name && IFS= read -r -d '' id; do
display "$name" "$id"
done < <(jq -j '
def stripnuls: sub("\u0000"; "<NUL>");
.[] | ((.name | stripnuls), "\u0000", (.id | stripnuls), "\u0000")
' <test.json)
您可以在https://replit.com/@CharlesDuffy2/BelovedForestgreenUnits#main.sh看到以上運行
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/406190.html
標籤:
上一篇:在Debian上的準備中強制是
