重要なヒント:使用中ですシビン
変更されたファイルからJSONを検索してからcurl
。 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
、またはPOSTにcontent-typeを使用し、それに対応します。ヘッダーをオーバーライドしようとすると変更されるとは思いません。 〜のように-d
--data
application/x-www-form-urlencoded
--data-ascii
基準たとえば、urlencodingの文字セットは、ここで完全に欠落しているフォーム要素によって異なります。
あなたのスクリプトを正しく理解すると、$result
urlencodeではなくUTF-8です。したがって、おそらく--data-urlencode
(詳細を参照)UTF-8を正しくエンコードしたい場合、またはより柔軟でcharsetフィールドを持つことができるものを使用する必要がman curl
あります。--form
したがって、主な問題は、標準がエンコードを指定する方法のようです。これは(少なくとも私にとって)理解するのは非常に難しいです。おそらくstackoverflowでより良い答えを得ることができます。