以 UTF-8 编码的 Curl JSON

以 UTF-8 编码的 Curl JSON

重要的提示: 我在用着西格文


我从更改的文件中检索 JSON,然后使用curl.到目前为止,一切都很好,除了一件事,当服务器接收 JSON 时,每个特殊字符(带重音符号等)都没有很好地编码。我想这是因为我的 JSON 在发送之前没有以 UTF-8 编码,但我无法转换它。

这是代码:

sed -i 's/\r//g' $file
fileContent=`cat $file`

result=$(jq -c -j ".docs[$docIndex] + { \"_rev\": \"$rev\" }"<<<"$fileContent")            result="{\"docs\":[$result]}"

result=$result | sed 's/\r//g'
result=$result | iconv -t "UTF-8"
s=$(curl -H "Content-Type: application/json; charset=UTF-8" -H "Cache-Control: no-cache" -d "$result" $2/$3/_bulk_docs --silent)

我的 bash 脚本和 JSON 文件都以 UTF-8 编码。我的 LANG 变量似乎是 UTF-8。我检查过这个:[[ $LANG =~ UTF-8$ ]] && echo "Uses UTF-8 encoding.."

任何想法?


更新

这是完整的脚本:

#!/bin/bash

# $1 = directory containing JSON files
# $2 = server url (+ port)
# $3 = database name

#Loop on every file of the given directory
for file in "$1"/*; do

    #Try to insert every document of a specific JSON file and retrieve their status (200 = OK; 409 = conflict)
    allStatus=$(curl -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data-binary "@$file" $2/$3/_bulk_docs --silent | jq '.[] |.status' | tr -d '\r')
    docIndex=0

    #Loop on every status (one status = one document)
    while IFS=' ' read -ra statusArray; do
      for status in "${statusArray[@]}"; do

        #Remove unwanted windows characters of the file
        sed -i 's/\r//g' $file
        fileContent=`cat $file`

        #Retrieve the id of the current document
        id=`jq -r -j ".docs[$docIndex]._id"<<<"$fileContent" | tr -d '\r'`

        if [ "$status" = "409" ]
        then 
            #Retrieve the revision of the current document and add it to the document 
            rev=$(curl -X GET --header 'Accept: application/json' $2/$3/$id?revs=true --silent | jq -r -j '._rev' | tr -d '\r')
            result=$(jq -c -j ".docs[$docIndex] + { \"_rev\": \"$rev\" }"<<<"$fileContent")

            #Wrap the document inside {"docs":[]}
            result="{\"docs\":[$result]}"

            #Remove unwanted windows characters before sending the document (again)
            result=$result | sed 's/\r//g'
            result=$result | iconv -t "UTF-8"
            s=$(curl -H "Content-Type: application/json; charset=UTF-8" -H "Cache-Control: no-cache" -d "$result" $2/$3/_bulk_docs --silent)

            #Echo result
            echo $s
        else
          #Status should be 200.
          echo 'status: '$status ' - ' $id
        fi

        docIndex=$((docIndex+1))

      done
    done <<< "$allStatus"
done

该脚本旨在在 NoSQL 数据库中更新插入文档。如果首先尝试插入,如果失败,它将检索文档的属性(修订版),追加到它,然后重试一次。

我知道这个脚本可以改进,但这是我的第一个 bash 脚本,它不会在生产中使用(仅用于测试等)。

答案1

只要您至少安装了 Python 2.7,您就可以在 Cygwin 上的 Bash 中使用它:

utf8_result="$(echo "$result" | python -c "import sys;[sys.stdout.write((i).decode('utf-8')) for i in sys.stdin]")"

答案2

部分答案:

根据man curl-d--data使用 content-type 进行 POST application/x-www-form-urlencoded,并且 相当于--data-ascii。我不认为尝试覆盖标头会改变这一点。作为标准说,urlencoding 的字符集取决于表单元素,这里完全缺少这些元素。

如果我正确理解你的脚本,$result它是 UTF-8,而不是 urlencoded。因此,您可能应该使用--data-urlencode(请参阅man curl详细信息),并希望它能够正确编码 UTF-8,或者您应该使用它--form,这样更灵活,并且可以在其中包含字符集字段。

因此,主要问题似乎在于标准如何规定编码,这非常难以理解(至少对我来说)。也许你可以在 stackoverflow 上得到更好的答案。

相关内容