중요한 팁: 사용 중입니다시빈
변경된 파일에서 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에서 더 나은 답변을 얻을 수 있을 것입니다.