【发布时间】:2021-11-28 05:15:10
【问题描述】:
我正在尝试在 bash 中解析无效的 JSON
x="{componentId: 00N5E000005vm9e, componentName: Field, referenceId: 0M05E0000002XbV, referenceName: RecordPageName1, referenceUrl: null, message: Component is in use by another component in your organization., reasonCode: 10}, {componentId: 00N5E000005vm9e, componentName: Field, referenceId: 0M05E0000002XbV, referenceName: RecordPageName1, referenceUrl: null, message: Component is in use by another component in your organization., reasonCode: 10}, {componentId: 00N5E000005vm9e, componentName: Field, referenceId: 0M05E0000002XbV, referenceName: RecordPageName1, referenceUrl: null, message: Component is in use by another component in your organization., reasonCode: 10}, {componentId: 0Rb5E000000BGVi, componentName: Versions, referenceId: 0M05E0000002XbV, referenceName: RecordPageName1, referenceUrl: null, message: Component is in use by another component in your organization., reasonCode: 10}, {componentId: 0Rb5E000000BGVj, componentName: Approves, referenceId: 0M05E0000002XbV, referenceName: RecordPageName1, referenceUrl: null, message: Component is in use by another component in your organization., reasonCode: 10}, {componentId: 0Rb5E000000BGVe, componentName: activityThreads, referenceId: 0M05E0000002XbV, referenceName: RecordPageName1, referenceUrl: null, message: Component is in use by another component in your organization., reasonCode: 10}, {componentId: 0Rb5E000000BGVf, componentName: Attachments, referenceId: 0M05E0000002XbV, referenceName: RecordPageName1, referenceUrl: null, message: Component is in use by another component in your organization., reasonCode: 10}, {componentId: 0Rb5E000000BGVh, componentName: Details, referenceId: 0M05E0000002XbV, referenceName: RecordPageName1, referenceUrl: null, message: Component is in use by another component in your organization., reasonCode: 10}"
使用以下脚本
for each in $(echo $x | sed 's/{componentId: /\n/g' ); do
echo "Each: $each"
echo [[ $each == 0Rb* ]]
if [[ $each == 0Rb* ]]; then
component=echo $each | awk -v FS="(componentName: |,|referenceName: |,)" '{print $3}'
reference=echo $each | awk -v FS="(componentName: |,|referenceName: |,)" '{print $6}'
echo "component: $component"
echo "reference: $component"
fi
done
但它不起作用。我不明白为什么它不起作用。当我在控制台中执行这一行时,
echo $x | sed 's/{componentId: /\n/g'
我可以看到这个无效的 json 被正确地分割成行,但是当我尝试将它传递到 for 循环中时,每个变量都会接收到更小的块值
Each: 00N5E000005vm9e,
我很困惑。
当componentId不以@开头时,我要做的是从无效的json中为每个项目提取componentName: 和,之间的值以及referenceName: 和,之间的另一个值987654331@。有没有办法做到这一点?
我也尝试使用jq -n $x,但使用jq: error: syntax error, unexpected IDENT, expecting '}' (Unix shell quoting issues?) at <top-level>, line 1: 失败
【问题讨论】:
-
对于“
for var in value”,拆分基于空格(空格、制表符、换行符...)而不仅仅是换行符。使用while IFS= read line循环,而不是将您的sed命令通过管道传递给它。 -
当我尝试使用
echo $x | while IFS= read -r each; do时,它将整个json作为一个变量 -
只要把它想象成非json,而不是无效的json。编写一个工具来解析它。
component=echo为什么要将echo分配给component?请使用 shellcheck 检查您的脚本并修复错误。为什么它是无效的 json,为什么它无效?do is to extract the value要在 shell 中提取值,通常使用带有awk或sed的正则表达式。但是要以某种格式解析文件,请用更好的语言编写解析器,例如python或perl。jq -n $x您所有的变量扩展都缺少引号。请用 shellcheck 检查你的脚本。 -
I am confused.不带引号的命令替换的结果$(...)经历分词扩展,取决于IFS,默认情况下是空格(制表符、换行符和空格)。$(...)的结果在任何空格或换行符上被拆分为单词,因此$each一次变成一个单词。要阅读行,请阅读mywiki.wooledge.org/BashFAQ/001。 -
也许你可以使用 YAML 解析器,因为这个数据是 YAML 而不是 JSON