不可不知的shell中的IFS

Linux下有一个特殊的环境变量叫做IFS,叫做内部字段分隔符(internal field separator)。它可以决定项目列表或值的列表的分隔符,IFS的默认值为空格,Tab制表符或换行符。使用for循环读取项目的列表或直列表时,就会根据IFS的值判断列表中的个数,最终决定循环的次数。

默认情况下,bash shell会将下面的字符当做字段分隔符:空格、制表符、换行符。

ASCLL码表

不可不知的shell中的IFS_第1张图片

不可不知的shell中的IFS_第2张图片

IPFS的值是空格或Tab制表符

当我们在终端上使用echo命令输出IFS的值时,因为IFS的值是空格或Tab制表符,所以无法显示具体的内容。

在这里插入图片描述

还有就是IFS的值还可以是一个换行符,上面输出结果就可以看出,是一个空白行。echo命令在输出数据内容后又会自动进行一次换行,所以最后输出两个空白行。

printf 命令输出IFS值

下面使用printf命令输出IFS值:
在这里插入图片描述

从上面的输出信息来看,输出IFS值,只有一个空白行,不会输出有两个空白行的情况发生,因为printf打印完内容后默认不换行。

使用od命令查看

在上面的输出结果来看。不管是使用echo还是printf命令,在输出的结果中都无法显式地查看到具体的内容。但是我们可以通过od命令将数据转换为八进制或者十六进制后再查看:

语法:

od(选项)(参数)

常用选项:

-a:此参数的效果和同时指定“-ta”参数相同;
-b:此参数的效果和同时指定“-toC”参数相同;
-c:此参数的效果和同时指定“-tC”参数相同;
-d:此参数的效果和同时指定“-tu2”参数相同;
-f:此参数的效果和同时指定“-tfF”参数相同;
-h:此参数的效果和同时指定“-tx2”参数相同;
-i:此参数的效果和同时指定“-td2”参数相同;
-j<字符数目>或–skip-bytes=<字符数目>:略过设置的字符数目;
-o:此参数的效果和同时指定“-to2”参数相同;
-s<字符串字符数>或–strings=<字符串字符数>:只显示符合指定的字符数目的字符串;
-t<输出格式>或–format=<输出格式>:设置输出格式;
-w<每列字符数>或–width=<每列字符数>:设置每列的最大字符数;

不可不知的shell中的IFS_第3张图片
从上面的输出结果来看,八进制040是空格,011是Tab制表符,012是换行符。因为IFS的原始值不容易设置,所以当需要修改IFS值时,最好提前备份原始值。

IFS修改

Bash shell会将上面的三个字符当做列表中新字段的开始。例如,zhangsan lisi wangwu字符串在shell中会当做三个字段zhangsan ;lisi ;wangwu。如果想要以逗号分隔字段,则要修改IFS的值,修改如下:

IFS=';'

定义分隔符为分号,变量X的值也使用分号分隔,循环遍历,每次循环输出一个名字。

#!/bin/bash

IFS=";"

X="zhangsan;lisi;wangwu"
for i in $X
do
        echo "I am $i."
done
echo

输出:
不可不知的shell中的IFS_第4张图片

通常我们需要设置IFS为分号、句号、或者冒号,之类的分隔符时,可以通过变量赋值的方式直接设置。例如IFS=";",但是不要直接通过IFS="\t"或者"\r"、“\a"将分隔符设置为制表符,不然系统会使用字母t作为分隔符。

那么应该如何地正确使用特殊字符设置为系统默认的分隔符呢?

不可不知的shell中的IFS_第5张图片

注意,输出的时候a、b、c之间使用Tab制表符分隔。如果输入的值之间没有使用Tab制表符分隔,而是使用t分隔,则系统会认为"atbtct"是一个整体的字符串。并将字符串赋给变量a,最后使用echo命令回显b和c时则为空。

总结

IFS是存储定界符的环境变量,是shell环境中的默认定界符字符串,默认值为空白字符(换行符、制表符、空格)。

你可能感兴趣的:(Linux,shell)