IFS 的范围是什么

IFS 的范围是什么

我对 IFS 的范围感到困惑,不同的人似乎认为它是基于会话的,而不是在设置/更改后仅在脚本内。

我的问题是,我有一个读取操作,其中可能包含空白列,这会偏移我设置的变量。如果我从制表符更改数据中的分隔符,并更新 IFS 以使用该新分隔符,我担心这可能会影响我的工作流程中的其他读取命令。

如果我做类似的事情:

while IFS='|' read var1 var2 var3

这是否只会改变该特定 while 循环的 IFS 值?

答案1

这是否只会改变该特定 while 循环的 IFS 值?

不,实际上它只会改变循环主体read内的部分while,之后它将返回其默认值,因为它仅在命令上下文中设置read

您可以对某个文件编写一个简单的循环来证明这一点,例如使用包含两列的 CSV 文件:

#!/bin/bash
while IFS="," read a b; do
  echo $a $b
done < "input.csv"
echo $IFS

输出的最后一行将显示为空,因为默认情况下,IFS 为<space><tab><newline>,因此$' \t\n'。请参阅请参阅 POSIX 规范以了解详细信息

如果您(意外地?)将整个脚本的 IFS 设置为其他值,unset IFS则将其重置为默认值。

此外,如果“会话”指的是单个脚本(或执行脚本的 shell),那么一旦该脚本退出,该值将不会被保存。当然,您的终端也不会在多个会话中保留它。

答案2

while IFS='|' read var1 var2 var3

这是否只会改变该特定 while 循环的 IFS 值?

不会。它只会改变该特定的 IFS 值read一般循环从whiledone,可能包含很多命令。

这里没有IFS什么read特殊的。以这个通用代码为例:

( export a=0
printenv a
while a=1 printenv a && printenv a; printenv a; true; do
   printenv a
   break
done; printenv a )

结果是:

0
1
0
0
0
0

只有第二个printenv获得修改后的值!

笔记:

  • 我使用子shell有两个原因:
    1. 你可以在 shell 执行任何操作之前粘贴整个代码;
    2. 该代码不会影响a当前 shell 中的变量。
  • 我使用了printenv a,而不是echo $a因为在后一种情况下,shell 将扩展$a到看到的值外壳本身甚至在echo启动之前(无论echo是 shell 内置命令还是单独的可执行文件)。语法variable=foo some_command几乎从不更改 shell 本身的变量(例外是variable=foo export variable)。如果您将我的代码中的每个变量printenv a都更改为,您将得到全部-s。echo $a0

答案3

在 shell 脚本中,IFS 代表内部字段分隔符。它是一个特殊的环境变量,用于确定 shell 如何将单词拆分为字段或标记。IFS 的默认值是空格(空格、制表符和换行符),这意味着默认情况下,shell 会在这些空格字符处拆分单词。

当您使用 read 命令而不指定分隔符时,IFS 用于根据空格字符将输入拆分为字段。每个字段都分配给一个单独的变量。

例子:

#!/bin/bash
line="Hello,World"
IFS=',' read -r field1 field2 <<< "$line"
echo "Field 1: $field1"
echo "Field 2: $field2"

答案4

是的,按照您的代码块,IFS 值仅针对循环设置。一旦控制退出循环,IFS 将在进入循环之前获得其值。这不会影响同一 shell 脚本中的其他读取操作。我尝试了类似这样的操作:

echo "Changing IFS value to ','."
OLD_IFS_VALUE=$IFS
IFS='|'
CURRENT_IFS_VALUE=$IFS
echo "IFS value before entering the loop : $CURRENT_IFS_VALUE"
while IFS=',' read name age city gender
do
    echo $name $age $city $gender
done < "testdata1.csv"
echo "After loop value of IFS : $IFS"

因此,我在循环之前将 IFS 设置为“|”。在循环内部,我使用 IFS 值作为“,”。一旦控件退出循环,IFS 值就是“|”。

相关内容