• IFS简单说明


    bash下的很多命令都会分割单词,绝大多数时候默认是采用空格作为分隔符,有些时候遇到制表符、换行符也会进行分隔。最典型的是"for i in a b c",它会分割变量列表"a b c"使其成为三个变量。这种分隔符是由IFS变量指定的。

    IFS是bash内部字段分隔符的环境变量。

    [root@localhost ~]# set | grep IFS
    IFS=$' 	
    '

    默认的IFS在碰到空格、制表符 和分行符 就会自动分隔进入下一步。但是对空格处理有点不一样,对行首和行尾两边的空格不处理,并且多个连续的空格默认当作一个空格。

    有些时候在编写脚本或执行循环的时候,修改IFS可以起很大作用。如果要修改IFS,最好记得先备份系统IFS,再需要的地方再还原IFS。

    例如:

    [root@localhost ~]# data="name,sex,rollno,location"
    [root@localhost ~]# oldIFS=$IFS
    [root@localhost ~]# IFS=$','
    [root@localhost ~]# for item in $data;do echo Item:$item;done
    Item:name
    Item:sex
    Item:rollno
    Item:location
    [root@localhost ~]# IFS=$oldIFS

    可以看到,上面的示例将默认分隔符设置为了逗号后,不用处理data变量就可以轻松划分字段了。

    再来一个有趣的示例:逐字符打印各个字符。

    [root@localhost ~]# cat /etc/resolv.conf | (IFS=$'34';while read -N 1 x;do /usr/bin/printf "%s" "$x";sleep 0.1; done)
    # Generated by NetworkManager
    nameserver 114.114.114.114
    nameserver fe80::1%ens33

    上面的while read -N 1 x表示每次读取一个字符并保存到变量x中,因为可能读取到空格或换行符,使得printf输出时无法输出,所以修改了IFS的值,将其设置为"34",这是一个控制字符,不可能出现在文件中,所以对文件中任何一个字符都很安全。

    [root@localhost ~]# cat /etc/passwd |(IFS=$'34'; while read -N 1 x;do /usr/bin/printf "%s" "$x";sleep 0.1; done)

    大多数时候,我们都不会去修改IFS也不会想到通过修改IFS来达到某种目的,而是采用其他方法来替代实现。这样就需要注意默认IFS(" ")的一个特殊性,它会忽略前导空白和后缀空白,并压缩连续空白。在某些时候,这会出现意想不到的问题。

    例如:

    [root@localhost ~]# a=-s" "
    [root@localhost ~]# echo "$a" | wc -m
    4

    实际上这里的$a是3个字符组成的,最后一个字符为空格。如果不对变量加引号,那么很多情况下都会出现问题:

    [root@localhost ~]# a=-s" "
    [root@localhost ~]#  echo $a | wc -m 
    3
    # s后面的空格被忽略了
    [root@localhost ~]# echo "${a:2}" | wc -m
    2
     # 截取到了s后面的空格
    [root@localhost ~]# echo ${a:2} | wc -m 
    1
     # 没有截取到s后面的空格
    [root@localhost ~]# expr substr $a 3 100 | wc -m
    1
    # 没有截取到s后面的空格
    [root@localhost ~]# expr substr "$a" 3 100 | wc -m
    2
    # 截取到了s后面的空格

    因此,在可以对变量加引号的情况下,尽100个可能地加上引号来保护空白字符。

  • 相关阅读:
    POJ 1163 状态转移
    POJ 1143 记忆化搜索+博弈论
    POJ 1083
    POJ 1018
    HDU 3572 Dinic
    HDU 3549 Dinic
    配置JDK环境变量配置及path和classpath的作用
    frameset 框架整体退出登录的问题
    java计算时间差及比较时间大小(转)
    Android—Http连接之GET/POST请求
  • 原文地址:https://www.cnblogs.com/liujunjun/p/12003894.html
Copyright © 2020-2023  润新知