Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何阻止'read'与'IFS'合并在一起的空白字符?_Linux_Bash_Shell_Whitespace_Ifs - Fatal编程技术网

Linux 如何阻止'read'与'IFS'合并在一起的空白字符?

Linux 如何阻止'read'与'IFS'合并在一起的空白字符?,linux,bash,shell,whitespace,ifs,Linux,Bash,Shell,Whitespace,Ifs,以这段代码为例,它读取由| DATA1="Andreas|Sweden|27" DATA2="JohnDoe||30" # <---- UNKNOWN COUNTRY while IFS="|" read -r NAME COUNTRY AGE; do echo "NAME: $NAME"; echo "COUNTRY: $COUNTRY"; echo &

以这段代码为例,它读取由
|

DATA1="Andreas|Sweden|27"
DATA2="JohnDoe||30"   # <---- UNKNOWN COUNTRY
while IFS="|" read -r NAME COUNTRY AGE; do 
    echo "NAME:    $NAME";
    echo "COUNTRY: $COUNTRY";
    echo "AGE:     $AGE";
done<<<"$DATA2"
DATA1="Andreas  Sweden  27"
DATA2="JohnDoe      30"  # <---- THERE ARE TWO TABS HERE
while IFS=$'\t' read -r NAME COUNTRY AGE; do 
    echo "NAME:    $NAME";
    echo "COUNTRY: $COUNTRY";
    echo "AGE:     $AGE";
done<<<"$DATA2"
但事实并非如此

输出:

姓名:约翰多
国家:30
年龄:


Bash,或
read
IFS
或代码的其他部分在不应该的情况下将空格拼凑在一起。为什么会发生这种情况?我如何修复它?

bash
的行为正是它应该做的。从
bash
文档中:

shell将IFS的每个字符视为分隔符,并将其他扩展的结果拆分为这些字符上的单词。如果未设置IFS,或其值正好是
,则默认值,则忽略先前展开结果开头和结尾处的
序列,并且不在开头或结尾处的任何IFS字符序列用于分隔单词。如果IFS的值不是默认值,则忽略单词开头和结尾的空格字符空格和制表符序列,只要空格字符在IFS的值中(IFS空格字符)。IFS中非IFS空格的任何字符,以及任何相邻的IFS空格字符,都会分隔字段。IFS空格字符序列也被视为分隔符

要克服此“功能”,您可以执行以下操作:

#!/bin/bash

DATA1="Andreas  Sweden  27"
DATA2="JohnDoe          30"  # <---- THERE ARE TWO TABS HERE

echo "$DATA2" | sed 's/\t/;/g' |
while IFS=';' read -r NAME COUNTRY AGE; do
    echo "NAME:    $NAME"
    echo "COUNTRY: $COUNTRY"
    echo "AGE:     $AGE"
done
#/bin/bash
DATA1=“安德烈亚斯瑞典27”

DATA2=“JohnDoe 30”#完全正确。外壳的存在是为了方便,它有很多特殊的情况,有时非常方便。要进行更精确的工作,请使用阶梯。Awk几乎总是足够的:
Awk{print”NAME:\t“$1”\n国家:\t“$2”\n管理:\t“$3}”FS=$'\t”放在一边:根据POSIX规范,所有caps变量都位于一个命名空间中,用于对shell和其他POSIX指定工具有意义的变量;而至少有一个小写字符的名称则保留给应用程序使用。请参阅,请记住,shell和环境变量共享一个名称空间,因此约定必须同时适用于这两个名称空间(因为设置shell变量会更新和覆盖任何类似的命名环境变量)。@CharlesDuffy。您可能需要再次阅读第8.1节。它对shell变量保持沉默;它只讨论环境变量。此外,该标准对共享单个名称空间的环境变量和外壳变量没有规定。POSIX sh标准要求分配给共享环境变量名称的任何外壳变量,以修改该环境变量。如果这并不意味着它们在同一个命名空间中,那么你会考虑如何组成共享命名空间呢?一旦你接受它们在同一个名称空间中,那么8.1就适用于shell变量。无论如何,如果你想争论它们不在同一个名称空间中,请告诉我如何修改PATH shell变量而不修改PATH环境变量。如果修改shell变量也会修改具有相同名称的环境变量,那么当您创建一个all caps shell变量时,您如何确定您是否也在不知不觉中修改了POSIX兼容实用程序使用的命名空间中的环境变量?