如何在Bash脚本中通过Python正确显示JSON中的带重音特殊字符
非ASCII字符解析显示异常解决方案
问题根因
- 你使用的是Python 2版本,默认标准输出采用ASCII编码,遇到葡萄牙语重音这类非ASCII字符时会直接抛出
UnicodeEncodeError,你添加了2> /dev/null将错误输出丢弃,因此对应变量取值为空,表现为字段缺失。 - 若Shell环境的locale未配置为UTF-8编码,也会导致字符解析异常。
解决方案
方案1:修改Python代码强制UTF-8输出(无需改动环境)
在每段Python执行代码中指定标准输出为UTF-8编码,修改后的代码示例:
getMovieInfo() { movieInfo=$(httpGet "https://api.themoviedb.org/3/movie/566525?api_key=b2f8880475c888056b6207067fbaa197&append_to_response=videos&language=pt-BR") genreOne=$(echo "$movieInfo" | python -c "import sys, json, codecs; sys.stdout = codecs.getwriter('utf8')(sys.stdout); print json.load(sys.stdin)['genres'][0]['name']" 2> /dev/null ) genreTwo=$(echo "$movieInfo" | python -c "import sys, json, codecs; sys.stdout = codecs.getwriter('utf8')(sys.stdout); print json.load(sys.stdin)['genres'][1]['name']" 2> /dev/null ) genreThree=$(echo "$movieInfo" | python -c "import sys, json, codecs; sys.stdout = codecs.getwriter('utf8')(sys.stdout); print json.load(sys.stdin)['genres'][2]['name']" 2> /dev/null ) genres=$(echo "$genreOne $genreTwo $genreThree" | tr " " ",") overview=$(echo "$movieInfo" | python -c "import sys, json, codecs; sys.stdout = codecs.getwriter('utf8')(sys.stdout); print json.load(sys.stdin)['overview']" 2> /dev/null ) }
方案2:切换为Python 3执行(更简洁)
Python 3默认采用UTF-8编码处理字符,仅需将代码中的python改为python3,同时给print语法添加括号即可:
genreOne=$(echo "$movieInfo" | python3 -c "import sys, json; print(json.load(sys.stdin)['genres'][0]['name'])" 2> /dev/null )
其余字段的解析逻辑同理修改即可。
方案3:全局配置Shell编码
在脚本开头添加编码环境变量配置,确保全局采用UTF-8解析字符:
export LC_ALL=en_US.UTF-8 export LANG=en_US.UTF-8
也可根据需求替换为pt_BR.UTF-8等对应语言的UTF-8 locale。
优化建议
你当前的代码对同一份JSON重复调用4次Python进程解析,性能开销较大,可一次性解析所有需要的字段,优化后代码示例:
getMovieInfo() { movieInfo=$(httpGet "https://api.themoviedb.org/3/movie/566525?api_key=b2f8880475c888056b6207067fbaa197&append_to_response=videos&language=pt-BR") # 一次性读取所有需要的字段 read -r genreOne genreTwo genreThree overview < <(echo "$movieInfo" | python -c " import sys, json, codecs sys.stdout = codecs.getwriter('utf8')(sys.stdout) data = json.load(sys.stdin) genres = [g['name'] for g in data['genres'][:3]] # 不足3个分类时补空值,避免拼接异常 while len(genres) < 3: genres.append('') print(' '.join(genres + [data['overview']])) " 2> /dev/null) genres="${genreOne},${genreTwo},${genreThree}" }
排查问题时可先临时去掉2> /dev/null配置,即可直接看到Python抛出的具体报错,提升定位效率。
内容的提问来源于stack exchange,提问作者Ruan Cabral
相关产品推荐
相关产品推荐

