Bash变量导致预期输出混乱



我试图创建一个JSON数据并将其存储到一个文件中,然后将其提供给我将要进行的API调用。但是,在格式化echo命令的输出以使JSON格式成为变量时,会导致返回的输出混乱。下面是我的脚本

cat "${SETTINGS_LIST}" | while read endpoint
do
echo "{"id": "$n", "method": GET, "url": "$endpoint"}"
let n=n+1
done

那么这就是SETTING_LIST变量

的内容
/accounting-rules
/aging-buckets
/application-rules
/audit-trail-settings
/batch-aliases
/billing-cycle-types
/billing-list-price-bases
/billing-period-starts
/billing-periods
/billing-rules

输出是这样返回的:

"}id":"0","method":"GET","url":"/accounting-rules
"}id":"1","method":"GET","url":"/aging-buckets
"}id":"2","method":"GET","url":"/application-rules
"}id":"3","method":"GET","url":"/audit-trail-settings
"}id":"4","method":"GET","url":"/batch-aliases
"}id":"5","method":"GET","url":"/billing-cycle-types
"}id":"6","method":"GET","url":"/billing-list-price-bases
"}id":"7","method":"GET","url":"/billing-period-starts
"}id":"8","method":"GET","url":"/billing-periods
"}id":"9","method":"GET","url":"/billing-rules

当我删除端点变量并将其更改为以下内容,例如

echo "{"id": "$n", "method": GET, "url": "/application-rules"}"

我得到了预期的输出

{"id": "0", "method": GET, "url": "/application-rules"}
{"id": "1", "method": GET, "url": "/application-rules"}
{"id": "2", "method": GET, "url": "/application-rules"}
{"id": "3", "method": GET, "url": "/application-rules"}
{"id": "4", "method": GET, "url": "/application-rules"}
{"id": "5", "method": GET, "url": "/application-rules"}
{"id": "6", "method": GET, "url": "/application-rules"}
{"id": "7", "method": GET, "url": "/application-rules"}
{"id": "8", "method": GET, "url": "/application-rules"}
{"id": "9", "method": GET, "url": "/application-rules"}

我做过的事:

  1. 已降级为git bash版本
  2. 在我的Ubuntu WSL中尝试,但仍然得到相同的错误。
  3. 尝试使用JQ和printf命令将输出格式化为JSON,但问题仍然存在
  4. 脚本可以在不同的机器上使用相同版本的BASH和GIT BASH

有人知道这个问题的原因和如何解决这个问题吗?

欢迎来上一堂关于Unix和Windows对行结束符的不同想法的小历史课!

在Unix(以及Linux, Ubuntu,…)上,行结束被定义为单个n字符。

在Windows上是两个字符序列rn

(为了完整起见,在旧的mac上它是一个单独的r,但这在今天基本上是无关紧要的。)

你有一个可爱的,windows兼容的文本文件,其中的行被rn分隔。然而,Bash作为一个Unix工具,并不专门处理r,并且只在n字符处分隔行。

因此,$endpoint变量的每个实例在末尾都包含一个r

现在,r也被称为"回车",来自老式打字机,这正是Bash的输出例程所做的,当它遇到r时:跳回当前行的开头,并用后面的字符替换所有字符。这就是为什么你会看到这样奇怪的、乱码的输出。

修正:删除r之前使用的变量。例:这个问题的答案建议这样解决:

cat "${SETTINGS_LIST}" | while IFS= read -r endpoint
do
endpoint="${endpoint%$'r'}"
echo "{"id": "$n", "method": GET, "url": "$endpoint"}"
let n=n+1
done

您的设置列表中显然有回车字符。将cat "${SETTINGS_LIST}"替换为dos2unix < "${SETTINGS_LIST}",即

dos2unix <"${SETTINGS_LIST}"` | while read endpoint

如果你还没有dos2unix(我不记得它是否随Mac发货),请从Appstore安装。