代码之家  ›  专栏  ›  技术社区  ›  Manuel Jordan

Bash和IFS:字符串拆分为具有特定分隔符的数组,并添加一个额外的空元素

  •  0
  • Manuel Jordan  · 技术社区  · 3 年前

    关于将字符串拆分为数组,我们有两种情况:

    如果字符串中有空格,如何使用分隔符,请按照以下帖子:

    因此,如果我使用:

    string="Hello Unix World"
    array1=($string)
    echo ${array1[@]}
    echo "size: '${#array1[@]}'"
    
    read -a array2 <<< $string
    echo ${array2[@]}
    echo "size: '${#array2[@]}'"
    

    Hello Unix World
    size: '3'
    Hello Unix World
    size: '3'
    

    这两种方法都能如期工作。

    现在,如果字符串中有不同于空格的内容,如何使用分隔符,请参见以下帖子:

    因此,如果我使用:

    path="/home/human/scripts"
    IFS='/' read -r -a array <<< "$path"
    
    echo "Approach 1"
    echo ${array[@]}
    echo "size: '${#array[@]}'"
    
    echo "Approach 2"
    for i in "${array[@]}"; do
       echo "$i"
    done
    
    echo "Approach 3"
    for (( i=0; i < ${#array[@]}; ++i )); do
        echo "$i: ${array[$i]}"
    done
    

    Approach 1
    home human scripts    <--- apparently all is ok, but see the line just below!
    size: '4'
    Approach 2
                          <--- an empty element
    home
    human
    scripts
    Approach 3
    0:                    <--- confirmed, the empty element
    1: home
    2: human
    3: scripts
    

    为什么会出现空元素?如何修复命令以避免这种情况?

    1 回复  |  直到 3 年前
        1
  •  1
  •   konsolebox    3 年前

    您的字符串分为4部分:一个空字符串和三个单词。

    path="/home/human/scripts"
    IFS='/' read -r -a array <<< "$path"
    declare -p array
    

    输出:

    declare -a array=([0]="" [1]="home" [2]="human" [3]="scripts")
    

    有很多方法可以解决这个问题。一种是删除空值。另一种方法是在分割之前排除起始斜杠。

    for i in "${!array[@]}"; do
        [[ ${array[i]} ]] || unset 'array[i]'
    done
    

    IFS='/' read -r -a array <<< "${path#/}"
    

    第一种方法适用于路径形式,因为斜杠不仅在开始时重复。

    推荐文章