带有Unicode的脚本中的IFS变量问题

DOS*_*DOS 1 variables bash shell ifs

IFS在shell脚本中使用变量来解析一些数据(数据已经以给定的格式提供给我).由于默认IFS是空格/制表符/等,我正在使用该字符'¬'来分隔输入文件行中的字段.数据类似于

14352345¬AFSFDG1234¬text¬(http://www.google.com,3)(http://www.test.com,2)¬(www.test2.com,4)¬123-23432
Run Code Online (Sandbox Code Playgroud)

我创建了一个脚本,使用IFS变量将文件管理到while循环中:

#!/bin/bash;
while IFS=¬ read -r sessionId qId testResults realResults queryId;
do echo $sessionId; done < inputFile
Run Code Online (Sandbox Code Playgroud)

(在这个循环中我实际上用另一个文件做了一些awk处理).

如果我手动运行此文件(只是./file),它会完美地运行.如果我将其作为脚本(cron)的一部分或在另一个脚本中运行,我会得到解析错误,这表明我的IFS变量未被使用.我试着复制了旧的IFS变量和分析,以及通过在IFS变量的不同方式后复位(¬,'¬',$'¬',等等,但似乎并没有帮助).

任何指针/提示将不胜感激.


更新:经过一些额外的调试,结果问题是awk语句而不是分隔符

小智 5

您要么遇到Unicode问题,要么使用您尝试使用的shell,前者更有可能.

您选择为separator(¬)的字符在ASCII集之外,并且可以(通常)由计算机以两种不同的方式表示:要么将其编码为latin1或类似字符,其中字符占用八位字节,或者它将被编码为UTF-8并使用两个八位字节.还有其他可能性,但这两种可能性最大,所以请耐心等待.

如果您保存编码为UTF-8的脚本并且您尝试在非unicode语言环境中运行它,则shell将获得两个(错误)字符作为分隔符而不是一个.要测试这一点,请尝试使用ascii字符作为分隔符,~例如.

如果您发现使用~有效,则必须查看系统的全局配置,并确保在用于创建脚本的环境中的语言环境相同,因为它位于以下环境中:脚本运行.您可以执行此locale命令.您可以创建一个运行此命令的脚本,并将其输出存储在一个文件中:

#!/bin/sh
locale > /tmp/locale-env
Run Code Online (Sandbox Code Playgroud)

然后你让它从cron运行,例如,看看/tmp/locale-env文件.将其内容与locale从交互式shell运行时的输出进行比较.根据您的分布,您可以设置您的全局区域中/etc/environment,/etc/profile或其他位置.您可能希望在系统范围内使用UTF-8:

LANG=en_US.UTF-8
export LANG
Run Code Online (Sandbox Code Playgroud)

这是一个陷阱,我们国际用户往往比英语用户更了解,因为ASCII和UTF-8对于英文字符完全相同,并且这些问题经常被忽视.