bash 字符串连接失败

bash 字符串连接失败

重要的提示: 我在用着西格文运行这个脚本。


我通过执行得到了一个json字符串

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

这是我得到的 JSON:

{"_id":"VT_CONSULTATION","name":"External Consultation","type":"VISIT_TYPE","sections":["HS_SECTION_AMBU"],"displayFields":[{"eventTypeId":"ET_CONSULTATION","elementValueTypeId":"EVT_IS_ACNC"},{"eventTypeId":"ET_CONSULTATION","elementValueTypeId":"EVT_MAIN_DIAGNOSTIC"},{"eventTypeId":"ET_CONSULTATION","elementValueTypeId":"EVT_IS_CONTROL_CONSULTATION","displayTrueValue":"Control visit","displayFalseValue":""}],"_rev":"rev"}

美化后:

{
    "_id": "VT_CONSULTATION",
    "name": "External Consultation",
    "type": "VISIT_TYPE",
    "sections": [
        "HS_SECTION_AMBU"
    ],
    "displayFields": [
        {
            "eventTypeId": "ET_CONSULTATION",
            "elementValueTypeId": "EVT_IS_ACNC"
        },
        {
            "eventTypeId": "ET_CONSULTATION",
            "elementValueTypeId": "EVT_MAIN_DIAGNOSTIC"
        },
        {
            "eventTypeId": "ET_CONSULTATION",
            "elementValueTypeId": "EVT_IS_CONTROL_CONSULTATION",
            "displayTrueValue": "Control visit",
            "displayFalseValue": ""
        }
    ],
    "_rev": "rev"
}

然后我想将这个字符串包装在里面,{"docs":[]}以便我之前的 JSON 被注入到docs[]数组中。

这是我所做的:

result="{\"docs\":["$result"]}"

但这是我得到的结果

{"docs":[{"_id":"VT_CONSULTATION","name":"External Consultation","type":"VISIT_TYPE","sections":["HS_SECTION_AMBU"],"displayFields":[{"eventTypeId":"ET_CONSULTATION","elementValueTypeId":"EVT_IS_ACNC"},{"eventTypeId":"ET_CONSULTATION","elementValueTypeId":"EVT_MAIN_DIAGNOSTIC"},{"eventTypeId":"ET_CONSULTATION","elementValueTypeId":"EVT_IS_CONTROL_CONSULTATION","displayTrueValue":"Control visit","displayFalseValue":""}],"_rev]}"rev"}

“失败”部分在哪里,"_rev]}"rev"}-> 它应该在哪里,"_rev":"rev"}]}

字符串连接过程中可能出现什么问题?


更新 这是完整的脚本(如果有帮助的话):

#!/bin/bash
for file in "$1"/*; do
    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
    while IFS=' ' read -ra statusArray; do
      for status in "${statusArray[@]}"; do
        if [ "$status" = "409" ]
        then
            sed -i 's/\r//g' $file
            fileContent=`cat $file`
            id=`jq -r ".docs[$docIndex]._id"<<<"$fileContent" | tr -d '\r'`
            rev=$(curl -X GET --header 'Accept: application/json' $2/$3/$id?revs=true --silent | jq -r '._rev' | tr -d '\r')
            result=$(jq -c ".docs[$docIndex] + { \"_rev\": \"rev\" }"<<<"$fileContent")
            result="{\"docs\":[$result]}"
            #Here result is broken
            s=$(curl -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d $result $2/$3/_bulk_docs --silent)
        else
          echo "No Conflict"
        fi
        docIndex=$((docIndex+1))
      done
    done <<< "$allStatus"
done

更新2 这是我调用后的结果echo "$result" | od -tx1(字符串连接后)

0000000 7b 22 64 6f 63 73 22 3a 5b 7b 22 5f 69 64 22 3a
0000020 22 56 54 5f 43 4f 4e 53 55 4c 54 41 54 49 4f 4e
0000040 22 2c 22 6e 61 6d 65 22 3a 22 45 78 74 65 72 6e
0000060 61 6c 20 43 6f 6e 73 75 6c 74 61 74 69 6f 6e 22
0000100 2c 22 74 79 70 65 22 3a 22 56 49 53 49 54 5f 54
0000120 59 50 45 22 2c 22 73 65 63 74 69 6f 6e 73 22 3a
0000140 5b 22 48 53 5f 53 45 43 54 49 4f 4e 5f 41 4d 42
0000160 55 22 5d 2c 22 64 69 73 70 6c 61 79 46 69 65 6c
0000200 64 73 22 3a 5b 7b 22 65 76 65 6e 74 54 79 70 65
0000220 49 64 22 3a 22 45 54 5f 43 4f 4e 53 55 4c 54 41
0000240 54 49 4f 4e 22 2c 22 65 6c 65 6d 65 6e 74 56 61
0000260 6c 75 65 54 79 70 65 49 64 22 3a 22 45 56 54 5f
0000300 49 53 5f 41 43 4e 43 22 7d 2c 7b 22 65 76 65 6e
0000320 74 54 79 70 65 49 64 22 3a 22 45 54 5f 43 4f 4e
0000340 53 55 4c 54 41 54 49 4f 4e 22 2c 22 65 6c 65 6d
0000360 65 6e 74 56 61 6c 75 65 54 79 70 65 49 64 22 3a
0000400 22 45 56 54 5f 4d 41 49 4e 5f 44 49 41 47 4e 4f
0000420 53 54 49 43 22 7d 2c 7b 22 65 76 65 6e 74 54 79
0000440 70 65 49 64 22 3a 22 45 54 5f 43 4f 4e 53 55 4c
0000460 54 41 54 49 4f 4e 22 2c 22 65 6c 65 6d 65 6e 74
0000500 56 61 6c 75 65 54 79 70 65 49 64 22 3a 22 45 56
0000520 54 5f 49 53 5f 43 4f 4e 54 52 4f 4c 5f 43 4f 4e
0000540 53 55 4c 54 41 54 49 4f 4e 22 2c 22 64 69 73 70
0000560 6c 61 79 54 72 75 65 56 61 6c 75 65 22 3a 22 43
0000600 6f 6e 74 72 6f 6c 20 76 69 73 69 74 22 2c 22 64
0000620 69 73 70 6c 61 79 46 61 6c 73 65 56 61 6c 75 65
0000640 22 3a 22 22 7d 5d 2c 22 5f 72 65 76 22 3a 22 72
0000660 65 76 22 7d 0d 5d 7d 0a
0000670

我在这里没有看到任何“异常”字符。

答案1

我认为 Steeldriver 的最后评论是正确的。我是 Cygwin 的经常用户,并且曾见过一些奇怪的事情发生在我错误地没有去掉回车符的文本中。

我们来做个实验吧。我对你的脚本进行了非常基本的提炼:

result="$(cat $1)"
result="{\"docs\":[$result]}"
echo $result

我的输入是

{"_id":"VT_CONSULTATION","name":"External Consultation","type":"VISIT_TYPE","sections":["HS_SECTION_AMBU"],"displayFields":[{"eventTypeId":"ET_CONSULTATION","elementValueTypeId":"EVT_IS_ACNC"},{"eventTypeId":"ET_CONSULTATION","elementValueTypeId":"EVT_MAIN_DIAGNOSTIC"},{"eventTypeId":"ET_CONSULTATION","elementValueTypeId":"EVT_IS_CONTROL_CONSULTATION","displayTrueValue":"Control visit","displayFalseValue":""}],"_rev":"rev"}

以正确的行结尾运行:

{"docs":[{"_id":"VT_CONSULTATION","name":"External Consultation","type":"VISIT_TYPE","sections":["HS_SECTION_AMBU"],"displayFields":[{"eventTypeId":"ET_CONSULTATION","elementValueTypeId":"EVT_IS_ACNC"},{"eventTypeId":"ET_CONSULTATION","elementValueTypeId":"EVT_MAIN_DIAGNOSTIC"},{"eventTypeId":"ET_CONSULTATION","elementValueTypeId":"EVT_IS_CONTROL_CONSULTATION","displayTrueValue":"Control visit","displayFalseValue":""}],"_rev":"rev"}]}

这就是我们所期望的。

现在我将一个回车符附加到输入行(在 vim 中使用 Ctrl-K+Ctrl-M)并再次运行:

{"docs":[{"_id":"VT_CONSULTATION","name":"External Consultation","type":"VISIT_TYPE","sections":["HS_SECTION_AMBU"],"displayFields":[{"eventTypeId":"ET_CONSULTATION","elementValueTypeId":"EVT_IS_ACNC"},{"eventTypeId":"ET_CONSULTATION","elementValueTypeId":"EVT_MAIN_DIAGNOSTIC"},{"eventTypeId":"ET_CONSULTATION","elementValueTypeI]}:"EVT_IS_CONTROL_CONSULTATION","displayTrueValue":"Control visit","displayFalseValue":""}],"_rev":"rev"}

哎呀。看看决赛的]}结果(就在“EVT_IS_CONTROL_CONSULTATION”之前)。它们的偏移方式与您的偏移方式不完全相同,但这是一个可疑的相似之处。

其他控制字符也可以引起类似的效果。检查此类字符是否存在的一个简单方法是使用grep '[^[:print:]]'它查找任何“非打印”字符(即控制字符等不可见的字符)。如果 grep 返回任何内容来确认这一点,则有多种方法可以找到并修复有问题的字符。您可以使用相同的正则表达式sed例如。或者使用十六进制编辑器(甚至 vim/xxd)。如果它是 CR,那么 OP 使用的相同 sed 命令应该执行以下操作:sed 's/\r//g'

相关内容